blob: d40ef965c8a36591098a3882d28a0d3bfcf4d0ca [file] [log] [blame]
Don Newton379ae252019-04-01 12:17:06 -04001// 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 "github.com/mongodb/mongo-go-driver/mongo/options"
15 "github.com/mongodb/mongo-go-driver/x/bsonx"
16 "github.com/mongodb/mongo-go-driver/x/bsonx/bsoncore"
17 "github.com/mongodb/mongo-go-driver/x/mongo/driver/session"
18 "github.com/mongodb/mongo-go-driver/x/mongo/driver/topology"
19 "github.com/mongodb/mongo-go-driver/x/mongo/driver/uuid"
20 "github.com/mongodb/mongo-go-driver/x/network/command"
21 "github.com/mongodb/mongo-go-driver/x/network/connection"
22 "github.com/mongodb/mongo-go-driver/x/network/description"
23)
24
25// ListIndexes handles the full cycle dispatch and execution of a listIndexes command against the provided
26// topology.
27func ListIndexes(
28 ctx context.Context,
29 cmd command.ListIndexes,
30 topo *topology.Topology,
31 selector description.ServerSelector,
32 clientID uuid.UUID,
33 pool *session.Pool,
34 opts ...*options.ListIndexesOptions,
35) (*BatchCursor, error) {
36
37 ss, err := topo.SelectServer(ctx, selector)
38 if err != nil {
39 return nil, err
40 }
41
42 conn, err := ss.Connection(ctx)
43 if err != nil {
44 return nil, err
45 }
46 defer conn.Close()
47
48 if ss.Description().WireVersion.Max < 3 {
49 return legacyListIndexes(ctx, cmd, ss, conn, opts...)
50 }
51
52 lio := options.MergeListIndexesOptions(opts...)
53 if lio.BatchSize != nil {
54 elem := bsonx.Elem{"batchSize", bsonx.Int32(*lio.BatchSize)}
55 cmd.Opts = append(cmd.Opts, elem)
56 cmd.CursorOpts = append(cmd.CursorOpts, elem)
57 }
58 if lio.MaxTime != nil {
59 cmd.Opts = append(cmd.Opts, bsonx.Elem{"maxTimeMS", bsonx.Int64(int64(*lio.MaxTime / time.Millisecond))})
60 }
61
62 // If no explicit session and deployment supports sessions, start implicit session.
63 if cmd.Session == nil && topo.SupportsSessions() {
64 cmd.Session, err = session.NewClientSession(pool, clientID, session.Implicit)
65 if err != nil {
66 return nil, err
67 }
68 }
69
70 res, err := cmd.RoundTrip(ctx, ss.Description(), conn)
71 if err != nil {
72 closeImplicitSession(cmd.Session)
73 return nil, err
74 }
75
76 return NewBatchCursor(bsoncore.Document(res), cmd.Session, cmd.Clock, ss.Server, cmd.CursorOpts...)
77}
78
79func legacyListIndexes(
80 ctx context.Context,
81 cmd command.ListIndexes,
82 ss *topology.SelectedServer,
83 conn connection.Connection,
84 opts ...*options.ListIndexesOptions,
85) (*BatchCursor, error) {
86 lio := options.MergeListIndexesOptions(opts...)
87 ns := cmd.NS.DB + "." + cmd.NS.Collection
88
89 findCmd := command.Find{
90 NS: command.NewNamespace(cmd.NS.DB, "system.indexes"),
91 Filter: bsonx.Doc{
92 {"ns", bsonx.String(ns)},
93 },
94 }
95
96 findOpts := options.Find()
97 if lio.BatchSize != nil {
98 findOpts.SetBatchSize(*lio.BatchSize)
99 }
100 if lio.MaxTime != nil {
101 findOpts.SetMaxTime(*lio.MaxTime)
102 }
103
104 return legacyFind(ctx, findCmd, nil, ss, conn, findOpts)
105}