Skip to content

Commit 6f3105a

Browse files
GODRIVER-2701 (Master) Implement a variant of DropIndex that gets keys rather than name (#1707)
1 parent cd1b7b2 commit 6f3105a

File tree

3 files changed

+111
-12
lines changed

3 files changed

+111
-12
lines changed

internal/integration/index_view_test.go

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -581,6 +581,88 @@ func TestIndexView(t *testing.T) {
581581
}
582582
assert.Nil(mt, cursor.Err(), "cursor error: %v", cursor.Err())
583583
})
584+
mt.Run("drop with key", func(mt *mtest.T) {
585+
tests := []struct {
586+
name string
587+
models []mongo.IndexModel
588+
index any
589+
want string
590+
}{
591+
{
592+
name: "custom index name and unique indexes",
593+
models: []mongo.IndexModel{
594+
{
595+
Keys: bson.D{{"username", int32(1)}},
596+
Options: options.Index().SetUnique(true).SetName("myidx"),
597+
},
598+
},
599+
index: bson.D{{"username", int32(1)}},
600+
want: "myidx",
601+
},
602+
{
603+
name: "normal generated index name",
604+
models: []mongo.IndexModel{
605+
{
606+
Keys: bson.D{{"foo", int32(-1)}},
607+
},
608+
},
609+
index: bson.D{{"foo", int32(-1)}},
610+
want: "foo_-1",
611+
},
612+
{
613+
name: "compound index",
614+
models: []mongo.IndexModel{
615+
{
616+
Keys: bson.D{{"foo", int32(1)}, {"bar", int32(1)}},
617+
},
618+
},
619+
index: bson.D{{"foo", int32(1)}, {"bar", int32(1)}},
620+
want: "foo_1_bar_1",
621+
},
622+
{
623+
name: "text index",
624+
models: []mongo.IndexModel{
625+
{
626+
Keys: bson.D{{"plot1", "text"}, {"plot2", "text"}},
627+
},
628+
},
629+
// Key is automatically set to Full Text Search for any text index
630+
index: bson.D{{"_fts", "text"}, {"_ftsx", int32(1)}},
631+
want: "plot1_text_plot2_text",
632+
},
633+
}
634+
635+
for _, test := range tests {
636+
mt.Run(test.name, func(mt *mtest.T) {
637+
iv := mt.Coll.Indexes()
638+
indexNames, err := iv.CreateMany(context.Background(), test.models)
639+
640+
s, _ := test.index.(bson.D)
641+
for _, name := range indexNames {
642+
verifyIndexExists(mt, iv, index{
643+
Key: s,
644+
Name: name,
645+
})
646+
}
647+
648+
assert.NoError(mt, err)
649+
assert.Equal(mt, len(test.models), len(indexNames), "expected %v index names, got %v", len(test.models), len(indexNames))
650+
651+
err = iv.DropWithKey(context.Background(), test.index)
652+
assert.Nil(mt, err, "DropOne error: %v", err)
653+
654+
cursor, err := iv.List(context.Background())
655+
assert.Nil(mt, err, "List error: %v", err)
656+
for cursor.Next(context.Background()) {
657+
var idx index
658+
err = cursor.Decode(&idx)
659+
assert.Nil(mt, err, "Decode error: %v (document %v)", err, cursor.Current)
660+
assert.NotEqual(mt, test.want, idx.Name, "found index %v after dropping", test.want)
661+
}
662+
assert.Nil(mt, cursor.Err(), "cursor error: %v", cursor.Err())
663+
})
664+
}
665+
})
584666
mt.Run("drop all", func(mt *mtest.T) {
585667
iv := mt.Coll.Indexes()
586668
names, err := iv.CreateMany(context.Background(), []mongo.IndexModel{

mongo/index_view.go

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -383,7 +383,7 @@ func (iv IndexView) createOptionsDoc(opts options.Lister[options.IndexOptions])
383383
return optsDoc, nil
384384
}
385385

386-
func (iv IndexView) drop(ctx context.Context, name string, _ ...options.Lister[options.DropIndexesOptions]) error {
386+
func (iv IndexView) drop(ctx context.Context, index any, _ ...options.Lister[options.DropIndexesOptions]) error {
387387
if ctx == nil {
388388
ctx = context.Background()
389389
}
@@ -409,8 +409,7 @@ func (iv IndexView) drop(ctx context.Context, name string, _ ...options.Lister[o
409409

410410
selector := makePinnedSelector(sess, iv.coll.writeSelector)
411411

412-
op := operation.NewDropIndexes(name).
413-
Session(sess).WriteConcern(wc).CommandMonitor(iv.coll.client.monitor).
412+
op := operation.NewDropIndexes(index).Session(sess).WriteConcern(wc).CommandMonitor(iv.coll.client.monitor).
414413
ServerSelector(selector).ClusterClock(iv.coll.client.clock).
415414
Database(iv.coll.db.name).Collection(iv.coll.name).
416415
Deployment(iv.coll.client.deployment).ServerAPI(iv.coll.client.serverAPI).
@@ -448,8 +447,19 @@ func (iv IndexView) DropOne(
448447
return iv.drop(ctx, name, opts...)
449448
}
450449

451-
// DropAll executes a dropIndexes operation to drop all indexes on the
452-
// collection.
450+
// DropWithKey drops a collection index by key using the dropIndexes operation.
451+
//
452+
// This function is useful to drop an index using its key specification instead of its name.
453+
func (iv IndexView) DropWithKey(ctx context.Context, keySpecDocument interface{}, opts ...options.Lister[options.DropIndexesOptions]) error {
454+
doc, err := marshal(keySpecDocument, iv.coll.bsonOpts, iv.coll.registry)
455+
if err != nil {
456+
return err
457+
}
458+
459+
return iv.drop(ctx, doc, opts...)
460+
}
461+
462+
// DropAll executes a dropIndexes operation to drop all indexes on the collection.
453463
//
454464
// The opts parameter can be used to specify options for this operation (see the
455465
// options.DropIndexesOptions documentation).

x/mongo/driver/operation/drop_indexes.go

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import (
2323

2424
// DropIndexes performs an dropIndexes operation.
2525
type DropIndexes struct {
26-
index *string
26+
index any
2727
session *session.Client
2828
clock *session.ClusterClock
2929
collection string
@@ -64,9 +64,9 @@ func buildDropIndexesResult(response bsoncore.Document) (DropIndexesResult, erro
6464
}
6565

6666
// NewDropIndexes constructs and returns a new DropIndexes.
67-
func NewDropIndexes(index string) *DropIndexes {
67+
func NewDropIndexes(index any) *DropIndexes {
6868
return &DropIndexes{
69-
index: &index,
69+
index: index,
7070
}
7171
}
7272

@@ -105,19 +105,26 @@ func (di *DropIndexes) Execute(ctx context.Context) error {
105105

106106
func (di *DropIndexes) command(dst []byte, _ description.SelectedServer) ([]byte, error) {
107107
dst = bsoncore.AppendStringElement(dst, "dropIndexes", di.collection)
108-
if di.index != nil {
109-
dst = bsoncore.AppendStringElement(dst, "index", *di.index)
108+
109+
switch di.index.(type) {
110+
case string:
111+
dst = bsoncore.AppendStringElement(dst, "index", di.index.(string))
112+
case bsoncore.Document:
113+
if di.index != nil {
114+
dst = bsoncore.AppendDocumentElement(dst, "index", di.index.(bsoncore.Document))
115+
}
110116
}
117+
111118
return dst, nil
112119
}
113120

114121
// Index specifies the name of the index to drop. If '*' is specified, all indexes will be dropped.
115-
func (di *DropIndexes) Index(index string) *DropIndexes {
122+
func (di *DropIndexes) Index(index any) *DropIndexes {
116123
if di == nil {
117124
di = new(DropIndexes)
118125
}
119126

120-
di.index = &index
127+
di.index = index
121128
return di
122129
}
123130

0 commit comments

Comments
 (0)