Skip to content

Commit 57b3e94

Browse files
authored
CLOUDP-60028: Implement index creation in atlas client (#75)
1 parent 923d69b commit 57b3e94

File tree

3 files changed

+156
-0
lines changed

3 files changed

+156
-0
lines changed

mongodbatlas/indexes.go

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
package mongodbatlas
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"net/http"
7+
)
8+
9+
const indexesPath = "groups/%s/clusters/%s/index"
10+
11+
// IndexesService is an interface for interfacing with the clusters indexes
12+
// endpoints of the MongoDB Atlas API.
13+
// See more: https://docs.atlas.mongodb.com/reference/api/indexes/
14+
type IndexesService interface {
15+
Create(context.Context, string, string, *IndexConfiguration) (*Response, error)
16+
}
17+
18+
// IndexesServiceOp handles communication with the Cluster related methods
19+
// of the MongoDB Atlas API
20+
type IndexesServiceOp struct {
21+
Client RequestDoer
22+
}
23+
24+
var _ IndexesService = &IndexesServiceOp{}
25+
26+
// IndexConfiguration represents a new index requests for a given database and collection.
27+
type IndexConfiguration struct {
28+
DB string `json:"db"` // DB the database of the index
29+
Collection string `json:"collection"` // Collection the collection of the index
30+
Keys []map[string]string `json:"keys"` // Keys array of keys to index and their type, sorting of keys is important for an index
31+
Options *IndexOptions `json:"options,omitempty"` // Options MongoDB index options
32+
Collation *CollationOptions `json:"collation,omitempty"` // Collation Mongo collation index options
33+
}
34+
35+
// IndexOptions, represents mdb index options
36+
// See: https://docs.mongodb.com/manual/reference/method/db.collection.createIndex/#options
37+
type IndexOptions struct {
38+
Background bool `json:"background,omitempty"`
39+
PartialFilterExpression *map[string]interface{} `json:"partialFilterExpression,omitempty"`
40+
StorageEngine *map[string]interface{} `json:"storageEngine,omitempty"`
41+
Weights *map[string]int `json:"weights,omitempty"`
42+
DefaultLanguage string `json:"default_language,omitempty"`
43+
LanguageOverride string `json:"language_override,omitempty"`
44+
TextIndexVersion int `json:"textIndexVersion,omitempty"`
45+
TwodsphereIndexVersion int `json:"2dsphereIndexVersion,omitempty"`
46+
Bits int `json:"bits,omitempty"`
47+
Unique bool `json:"unique,omitempty"`
48+
Sparse bool `json:"sparse,omitempty"`
49+
GeoMin int `json:"min,omitempty"`
50+
GeoMax int `json:"max,omitempty"`
51+
BucketSize int `json:"bucketSize,omitempty"`
52+
Name string `json:"name,omitempty"`
53+
ExpireAfterSeconds int `json:"expireAfterSeconds,omitempty"`
54+
}
55+
56+
// CollationOptions represents options for collation indexes
57+
// See: https://docs.mongodb.com/manual/reference/method/db.collection.createIndex/#option-for-collation
58+
type CollationOptions struct {
59+
Locale string `json:"locale,omitempty"`
60+
CaseLevel bool `json:"caseLevel,omitempty"`
61+
CaseFirst string `json:"caseFirst,omitempty"`
62+
Strength int `json:"strength,omitempty"`
63+
NumericOrdering bool `json:"numericOrdering,omitempty"`
64+
Alternate string `json:"alternate,omitempty"`
65+
MaxVariable string `json:"maxVariable,omitempty"`
66+
Normalization bool `json:"normalization,omitempty"`
67+
Backwards bool `json:"backwards,omitempty"`
68+
}
69+
70+
// Create creates a request for a rolling index creation for the project associated to {GROUP-ID} and the {CLUSTER-NAME}.
71+
// See more: https://docs.atlas.mongodb.com/reference/api/rolling-index-create-one/
72+
func (s *IndexesServiceOp) Create(ctx context.Context, groupID string, clusterName string, createReq *IndexConfiguration) (*Response, error) {
73+
if groupID == "" {
74+
return nil, NewArgError("groupID", "must be set")
75+
}
76+
if clusterName == "" {
77+
return nil, NewArgError("clusterName", "must be set")
78+
}
79+
if createReq == nil {
80+
return nil, NewArgError("createReq", "must be set")
81+
}
82+
83+
path := fmt.Sprintf(indexesPath, groupID, clusterName)
84+
85+
req, err := s.Client.NewRequest(ctx, http.MethodPost, path, createReq)
86+
if err != nil {
87+
return nil, err
88+
}
89+
90+
resp, err := s.Client.Do(ctx, req, nil)
91+
92+
return resp, err
93+
}

mongodbatlas/indexes_test.go

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
package mongodbatlas
2+
3+
import (
4+
"encoding/json"
5+
"fmt"
6+
"net/http"
7+
"testing"
8+
9+
"github.com/go-test/deep"
10+
)
11+
12+
func TestIndexesServiceOp_Create(t *testing.T) {
13+
setup()
14+
defer teardown()
15+
16+
groupID := "1"
17+
clusterName := "appData"
18+
19+
createRequest := &IndexConfiguration{
20+
DB: "test",
21+
Collection: "test",
22+
Keys: []map[string]string{
23+
{
24+
"name": "1",
25+
},
26+
},
27+
Options: &IndexOptions{
28+
Unique: true,
29+
},
30+
}
31+
mux.HandleFunc(fmt.Sprintf("/groups/%s/clusters/%s/index", groupID, clusterName), func(w http.ResponseWriter, r *http.Request) {
32+
testMethod(t, r, http.MethodPost)
33+
expected := map[string]interface{}{
34+
"db": "test",
35+
"collection": "test",
36+
"keys": []interface{}{map[string]interface{}{
37+
"name": "1",
38+
}},
39+
"options": map[string]interface{}{
40+
"unique": true,
41+
},
42+
}
43+
44+
var v map[string]interface{}
45+
err := json.NewDecoder(r.Body).Decode(&v)
46+
if err != nil {
47+
t.Fatalf("decode json: %v", err)
48+
}
49+
50+
if diff := deep.Equal(v, expected); diff != nil {
51+
t.Errorf("Clusters.Update Request Body = %v", diff)
52+
}
53+
fmt.Fprint(w, "{}")
54+
})
55+
56+
_, err := client.Indexes.Create(ctx, groupID, clusterName, createRequest)
57+
58+
if err != nil {
59+
t.Fatalf("Indexes.Create returned error: %v", err)
60+
}
61+
}

mongodbatlas/mongodbatlas.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ type Client struct {
7070
ProcessDisks ProcessDisksService
7171
ProcessDiskMeasurements ProcessDiskMeasurementsService
7272
ProcessDatabases ProcessDatabasesService
73+
Indexes IndexesService
7374

7475
onRequestCompleted RequestCompletionCallback
7576
}
@@ -193,6 +194,7 @@ func NewClient(httpClient *http.Client) *Client {
193194
c.ProcessDisks = &ProcessDisksServiceOp{Client: c}
194195
c.ProcessDiskMeasurements = &ProcessDiskMeasurementsServiceOp{Client: c}
195196
c.ProcessDatabases = &ProcessDatabasesServiceOp{Client: c}
197+
c.Indexes = &IndexesServiceOp{Client: c}
196198

197199
return c
198200
}

0 commit comments

Comments
 (0)