Skip to content

Commit 2806752

Browse files
authored
GODRIVER-2221 add unique, expires, and sparse to index options (#794)
1 parent 223854c commit 2806752

File tree

2 files changed

+97
-13
lines changed

2 files changed

+97
-13
lines changed

mongo/integration/index_view_test.go

Lines changed: 75 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ func TestIndexView(t *testing.T) {
2929
mt := mtest.New(t, noClientOpts)
3030
defer mt.Close()
3131

32+
var pbool = func(b bool) *bool { return &b }
33+
var pint32 = func(i int32) *int32 { return &i }
34+
3235
mt.Run("list", func(mt *mtest.T) {
3336
createIndexes := func(mt *mtest.T, numIndexes int) {
3437
mt.Helper()
@@ -472,21 +475,84 @@ func TestIndexView(t *testing.T) {
472475
})
473476
mt.RunOpts("list specifications", noClientOpts, func(mt *mtest.T) {
474477
mt.Run("verify results", func(mt *mtest.T) {
475-
keysDoc := bsoncore.NewDocumentBuilder().AppendInt32("_id", 1).Build()
476-
expectedSpec := &mongo.IndexSpecification{
477-
Name: "_id_",
478-
Namespace: mt.DB.Name() + "." + mt.Coll.Name(),
479-
KeysDocument: bson.Raw(keysDoc),
480-
Version: 2,
478+
// Create a handful of indexes
479+
_, err := mt.Coll.Indexes().CreateMany(mtest.Background, []mongo.IndexModel{
480+
{
481+
Keys: bson.D{{"foo", int32(-1)}},
482+
Options: options.Index().SetUnique(true),
483+
},
484+
{
485+
Keys: bson.D{{"bar", int32(1)}},
486+
Options: options.Index().SetExpireAfterSeconds(120),
487+
},
488+
{
489+
Keys: bson.D{{"baz", int32(1)}},
490+
Options: options.Index().SetSparse(true),
491+
},
492+
{
493+
Keys: bson.D{{"bar", int32(1)}, {"baz", int32(-1)}},
494+
},
495+
})
496+
assert.Nil(mt, err, "CreateMany error: %v", err)
497+
498+
expectedSpecs := []*mongo.IndexSpecification{
499+
{
500+
Name: "_id_",
501+
Namespace: mt.DB.Name() + "." + mt.Coll.Name(),
502+
KeysDocument: bson.Raw(bsoncore.NewDocumentBuilder().AppendInt32("_id", 1).Build()),
503+
Version: 2,
504+
ExpireAfterSeconds: nil,
505+
Sparse: nil,
506+
// ID index is special and does not return 'true', despite being unique.
507+
Unique: nil,
508+
},
509+
{
510+
Name: "foo_-1",
511+
Namespace: mt.DB.Name() + "." + mt.Coll.Name(),
512+
KeysDocument: bson.Raw(bsoncore.NewDocumentBuilder().AppendInt32("foo", -1).Build()),
513+
Version: 2,
514+
ExpireAfterSeconds: nil,
515+
Sparse: nil,
516+
Unique: pbool(true),
517+
},
518+
{
519+
Name: "bar_1",
520+
Namespace: mt.DB.Name() + "." + mt.Coll.Name(),
521+
KeysDocument: bson.Raw(bsoncore.NewDocumentBuilder().AppendInt32("bar", 1).Build()),
522+
Version: 2,
523+
ExpireAfterSeconds: pint32(120),
524+
Sparse: nil,
525+
Unique: nil,
526+
},
527+
{
528+
Name: "baz_1",
529+
Namespace: mt.DB.Name() + "." + mt.Coll.Name(),
530+
KeysDocument: bson.Raw(bsoncore.NewDocumentBuilder().AppendInt32("baz", 1).Build()),
531+
Version: 2,
532+
ExpireAfterSeconds: nil,
533+
Sparse: pbool(true),
534+
Unique: nil,
535+
},
536+
{
537+
Name: "bar_1_baz_-1",
538+
Namespace: mt.DB.Name() + "." + mt.Coll.Name(),
539+
KeysDocument: bson.Raw(bsoncore.NewDocumentBuilder().AppendInt32("bar", 1).AppendInt32("baz", -1).Build()),
540+
Version: 2,
541+
ExpireAfterSeconds: nil,
542+
Sparse: nil,
543+
Unique: nil,
544+
},
481545
}
482546
if mtest.CompareServerVersions(mtest.ServerVersion(), "3.4") < 0 {
483-
expectedSpec.Version = 1
547+
for _, expectedSpec := range expectedSpecs {
548+
expectedSpec.Version = 1
549+
}
484550
}
485551

486552
specs, err := mt.Coll.Indexes().ListSpecifications(mtest.Background)
487553
assert.Nil(mt, err, "ListSpecifications error: %v", err)
488-
assert.Equal(mt, 1, len(specs), "expected 1 specification, got %d", len(specs))
489-
assert.Equal(mt, expectedSpec, specs[0], "expected specification %v, got %v", expectedSpec, specs[0])
554+
assert.Equal(mt, len(expectedSpecs), len(specs), "expected %d specification, got %d", len(expectedSpecs), len(specs))
555+
assert.True(mt, cmp.Equal(specs, expectedSpecs), "expected specifications to match: %v", cmp.Diff(specs, expectedSpecs))
490556
})
491557
mt.RunOpts("options passed to listIndexes", mtest.NewOptions().MinServerVersion("3.0"), func(mt *mtest.T) {
492558
opts := options.ListIndexes().SetMaxTime(100 * time.Millisecond)

mongo/results.go

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -158,15 +158,30 @@ type IndexSpecification struct {
158158

159159
// The index version.
160160
Version int32
161+
162+
// The length of time, in seconds, for documents to remain in the collection. The default value is 0, which means
163+
// that documents will remain in the collection until they're explicitly deleted or the collection is dropped.
164+
ExpireAfterSeconds *int32
165+
166+
// If true, the index will only reference documents that contain the fields specified in the index. The default is
167+
// false.
168+
Sparse *bool
169+
170+
// If true, the collection will not accept insertion or update of documents where the index key value matches an
171+
// existing value in the index. The default is false.
172+
Unique *bool
161173
}
162174

163175
var _ bson.Unmarshaler = (*IndexSpecification)(nil)
164176

165177
type unmarshalIndexSpecification struct {
166-
Name string `bson:"name"`
167-
Namespace string `bson:"ns"`
168-
KeysDocument bson.Raw `bson:"key"`
169-
Version int32 `bson:"v"`
178+
Name string `bson:"name"`
179+
Namespace string `bson:"ns"`
180+
KeysDocument bson.Raw `bson:"key"`
181+
Version int32 `bson:"v"`
182+
ExpireAfterSeconds *int32 `bson:"expireAfterSeconds"`
183+
Sparse *bool `bson:"sparse"`
184+
Unique *bool `bson:"unique"`
170185
}
171186

172187
// UnmarshalBSON implements the bson.Unmarshaler interface.
@@ -180,6 +195,9 @@ func (i *IndexSpecification) UnmarshalBSON(data []byte) error {
180195
i.Namespace = temp.Namespace
181196
i.KeysDocument = temp.KeysDocument
182197
i.Version = temp.Version
198+
i.ExpireAfterSeconds = temp.ExpireAfterSeconds
199+
i.Sparse = temp.Sparse
200+
i.Unique = temp.Unique
183201
return nil
184202
}
185203

0 commit comments

Comments
 (0)