1// Copyright (C) MongoDB, Inc. 2017-present. 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); you may 4// not use this file except in compliance with the License. You may obtain 5// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 6 7package driver 8 9import ( 10 "context" 11 12 "time" 13 14 "go.mongodb.org/mongo-driver/mongo/options" 15 "go.mongodb.org/mongo-driver/x/bsonx" 16 "go.mongodb.org/mongo-driver/x/mongo/driver/session" 17 "go.mongodb.org/mongo-driver/x/mongo/driver/topology" 18 "go.mongodb.org/mongo-driver/x/mongo/driver/uuid" 19 "go.mongodb.org/mongo-driver/x/network/command" 20 "go.mongodb.org/mongo-driver/x/network/description" 21 "go.mongodb.org/mongo-driver/x/network/result" 22) 23 24// CreateIndexes handles the full cycle dispatch and execution of a createIndexes 25// command against the provided topology. 26func CreateIndexes( 27 ctx context.Context, 28 cmd command.CreateIndexes, 29 topo *topology.Topology, 30 selector description.ServerSelector, 31 clientID uuid.UUID, 32 pool *session.Pool, 33 opts ...*options.CreateIndexesOptions, 34) (result.CreateIndexes, error) { 35 36 ss, err := topo.SelectServer(ctx, selector) 37 if err != nil { 38 return result.CreateIndexes{}, err 39 } 40 41 desc := ss.Description() 42 if desc.WireVersion.Max < 5 && hasCollation(cmd) { 43 return result.CreateIndexes{}, ErrCollation 44 } 45 46 conn, err := ss.Connection(ctx) 47 if err != nil { 48 return result.CreateIndexes{}, err 49 } 50 defer conn.Close() 51 52 cio := options.MergeCreateIndexesOptions(opts...) 53 if cio.MaxTime != nil { 54 cmd.Opts = append(cmd.Opts, bsonx.Elem{"maxTimeMS", bsonx.Int64(int64(*cio.MaxTime / time.Millisecond))}) 55 } 56 57 // If no explicit session and deployment supports sessions, start implicit session. 58 if cmd.Session == nil && topo.SupportsSessions() { 59 cmd.Session, err = session.NewClientSession(pool, clientID, session.Implicit) 60 if err != nil { 61 return result.CreateIndexes{}, err 62 } 63 defer cmd.Session.EndSession() 64 } 65 66 return cmd.RoundTrip(ctx, ss.Description(), conn) 67} 68 69func hasCollation(cmd command.CreateIndexes) bool { 70 for _, ind := range cmd.Indexes { 71 if _, err := ind.Document().LookupErr("collation"); err == nil { 72 return true 73 } 74 } 75 76 return false 77} 78