Skip to content

GODRIVER-2221 add unique, expires, and sparse to index options #794

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Nov 9, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 75 additions & 9 deletions mongo/integration/index_view_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ func TestIndexView(t *testing.T) {
mt := mtest.New(t, noClientOpts)
defer mt.Close()

var pbool = func(b bool) *bool { return &b }
var pint32 = func(i int32) *int32 { return &i }

mt.Run("list", func(mt *mtest.T) {
createIndexes := func(mt *mtest.T, numIndexes int) {
mt.Helper()
Expand Down Expand Up @@ -472,21 +475,84 @@ func TestIndexView(t *testing.T) {
})
mt.RunOpts("list specifications", noClientOpts, func(mt *mtest.T) {
mt.Run("verify results", func(mt *mtest.T) {
keysDoc := bsoncore.NewDocumentBuilder().AppendInt32("_id", 1).Build()
expectedSpec := &mongo.IndexSpecification{
Name: "_id_",
Namespace: mt.DB.Name() + "." + mt.Coll.Name(),
KeysDocument: bson.Raw(keysDoc),
Version: 2,
// Create a handful of indexes
_, err := mt.Coll.Indexes().CreateMany(mtest.Background, []mongo.IndexModel{
{
Keys: bson.D{{"foo", int32(-1)}},
Options: options.Index().SetUnique(true),
},
{
Keys: bson.D{{"bar", int32(1)}},
Options: options.Index().SetExpireAfterSeconds(120),
},
{
Keys: bson.D{{"baz", int32(1)}},
Options: options.Index().SetSparse(true),
},
{
Keys: bson.D{{"bar", int32(1)}, {"baz", int32(-1)}},
},
})
assert.Nil(mt, err, "CreateMany error: %v", err)

expectedSpecs := []*mongo.IndexSpecification{
{
Name: "_id_",
Namespace: mt.DB.Name() + "." + mt.Coll.Name(),
KeysDocument: bson.Raw(bsoncore.NewDocumentBuilder().AppendInt32("_id", 1).Build()),
Version: 2,
ExpireAfterSeconds: nil,
Sparse: nil,
// ID index is special and does not return 'true', despite being unique.
Unique: nil,
},
{
Name: "foo_-1",
Namespace: mt.DB.Name() + "." + mt.Coll.Name(),
KeysDocument: bson.Raw(bsoncore.NewDocumentBuilder().AppendInt32("foo", -1).Build()),
Version: 2,
ExpireAfterSeconds: nil,
Sparse: nil,
Unique: pbool(true),
},
{
Name: "bar_1",
Namespace: mt.DB.Name() + "." + mt.Coll.Name(),
KeysDocument: bson.Raw(bsoncore.NewDocumentBuilder().AppendInt32("bar", 1).Build()),
Version: 2,
ExpireAfterSeconds: pint32(120),
Sparse: nil,
Unique: nil,
},
{
Name: "baz_1",
Namespace: mt.DB.Name() + "." + mt.Coll.Name(),
KeysDocument: bson.Raw(bsoncore.NewDocumentBuilder().AppendInt32("baz", 1).Build()),
Version: 2,
ExpireAfterSeconds: nil,
Sparse: pbool(true),
Unique: nil,
},
{
Name: "bar_1_baz_-1",
Namespace: mt.DB.Name() + "." + mt.Coll.Name(),
KeysDocument: bson.Raw(bsoncore.NewDocumentBuilder().AppendInt32("bar", 1).AppendInt32("baz", -1).Build()),
Version: 2,
ExpireAfterSeconds: nil,
Sparse: nil,
Unique: nil,
},
}
if mtest.CompareServerVersions(mtest.ServerVersion(), "3.4") < 0 {
expectedSpec.Version = 1
for _, expectedSpec := range expectedSpecs {
expectedSpec.Version = 1
}
}

specs, err := mt.Coll.Indexes().ListSpecifications(mtest.Background)
assert.Nil(mt, err, "ListSpecifications error: %v", err)
assert.Equal(mt, 1, len(specs), "expected 1 specification, got %d", len(specs))
assert.Equal(mt, expectedSpec, specs[0], "expected specification %v, got %v", expectedSpec, specs[0])
assert.Equal(mt, len(expectedSpecs), len(specs), "expected %d specification, got %d", len(expectedSpecs), len(specs))
assert.True(mt, cmp.Equal(specs, expectedSpecs), "expected specifications to match: %v", cmp.Diff(specs, expectedSpecs))
})
mt.RunOpts("options passed to listIndexes", mtest.NewOptions().MinServerVersion("3.0"), func(mt *mtest.T) {
opts := options.ListIndexes().SetMaxTime(100 * time.Millisecond)
Expand Down
26 changes: 22 additions & 4 deletions mongo/results.go
Original file line number Diff line number Diff line change
Expand Up @@ -158,15 +158,30 @@ type IndexSpecification struct {

// The index version.
Version int32

// The length of time, in seconds, for documents to remain in the collection. The default value is 0, which means
// that documents will remain in the collection until they're explicitly deleted or the collection is dropped.
ExpireAfterSeconds *int32

// If true, the index will only reference documents that contain the fields specified in the index. The default is
// false.
Sparse *bool

// If true, the collection will not accept insertion or update of documents where the index key value matches an
// existing value in the index. The default is false.
Unique *bool
}

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

type unmarshalIndexSpecification struct {
Name string `bson:"name"`
Namespace string `bson:"ns"`
KeysDocument bson.Raw `bson:"key"`
Version int32 `bson:"v"`
Name string `bson:"name"`
Namespace string `bson:"ns"`
KeysDocument bson.Raw `bson:"key"`
Version int32 `bson:"v"`
ExpireAfterSeconds *int32 `bson:"expireAfterSeconds"`
Sparse *bool `bson:"sparse"`
Unique *bool `bson:"unique"`
}

// UnmarshalBSON implements the bson.Unmarshaler interface.
Expand All @@ -180,6 +195,9 @@ func (i *IndexSpecification) UnmarshalBSON(data []byte) error {
i.Namespace = temp.Namespace
i.KeysDocument = temp.KeysDocument
i.Version = temp.Version
i.ExpireAfterSeconds = temp.ExpireAfterSeconds
i.Sparse = temp.Sparse
i.Unique = temp.Unique
return nil
}

Expand Down