blob: eed73905d5b8ab82aea295d1c95e0dcf1719c053 [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 "github.com/mongodb/mongo-go-driver/mongo/options"
12 "github.com/mongodb/mongo-go-driver/x/bsonx"
13
14 "github.com/mongodb/mongo-go-driver/x/mongo/driver/session"
15 "github.com/mongodb/mongo-go-driver/x/mongo/driver/topology"
16 "github.com/mongodb/mongo-go-driver/x/mongo/driver/uuid"
17 "github.com/mongodb/mongo-go-driver/x/network/command"
18 "github.com/mongodb/mongo-go-driver/x/network/description"
19 "github.com/mongodb/mongo-go-driver/x/network/result"
20 "time"
21)
22
23// Distinct handles the full cycle dispatch and execution of a distinct command against the provided
24// topology.
25func Distinct(
26 ctx context.Context,
27 cmd command.Distinct,
28 topo *topology.Topology,
29 selector description.ServerSelector,
30 clientID uuid.UUID,
31 pool *session.Pool,
32 opts ...*options.DistinctOptions,
33) (result.Distinct, error) {
34
35 ss, err := topo.SelectServer(ctx, selector)
36 if err != nil {
37 return result.Distinct{}, err
38 }
39
40 desc := ss.Description()
41 conn, err := ss.Connection(ctx)
42 if err != nil {
43 return result.Distinct{}, err
44 }
45 defer conn.Close()
46
47 rp, err := getReadPrefBasedOnTransaction(cmd.ReadPref, cmd.Session)
48 if err != nil {
49 return result.Distinct{}, err
50 }
51 cmd.ReadPref = rp
52
53 // If no explicit session and deployment supports sessions, start implicit session.
54 if cmd.Session == nil && topo.SupportsSessions() {
55 cmd.Session, err = session.NewClientSession(pool, clientID, session.Implicit)
56 if err != nil {
57 return result.Distinct{}, err
58 }
59 defer cmd.Session.EndSession()
60 }
61
62 distinctOpts := options.MergeDistinctOptions(opts...)
63
64 if distinctOpts.MaxTime != nil {
65 cmd.Opts = append(cmd.Opts, bsonx.Elem{
66 "maxTimeMS", bsonx.Int64(int64(*distinctOpts.MaxTime / time.Millisecond)),
67 })
68 }
69 if distinctOpts.Collation != nil {
70 if desc.WireVersion.Max < 5 {
71 return result.Distinct{}, ErrCollation
72 }
73 cmd.Opts = append(cmd.Opts, bsonx.Elem{"collation", bsonx.Document(distinctOpts.Collation.ToDocument())})
74 }
75
76 return cmd.RoundTrip(ctx, desc, conn)
77}