1// Copyright (C) MongoDB, Inc. 2019-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
7// Code generated by operationgen. DO NOT EDIT.
8
9package operation
10
11import (
12	"context"
13	"errors"
14	"fmt"
15
16	"go.mongodb.org/mongo-driver/event"
17	"go.mongodb.org/mongo-driver/mongo/readconcern"
18	"go.mongodb.org/mongo-driver/mongo/readpref"
19	"go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
20	"go.mongodb.org/mongo-driver/x/mongo/driver"
21	"go.mongodb.org/mongo-driver/x/mongo/driver/description"
22	"go.mongodb.org/mongo-driver/x/mongo/driver/session"
23)
24
25// Performs a count operation
26type Count struct {
27	maxTimeMS      *int64
28	query          bsoncore.Document
29	session        *session.Client
30	clock          *session.ClusterClock
31	collection     string
32	monitor        *event.CommandMonitor
33	crypt          *driver.Crypt
34	database       string
35	deployment     driver.Deployment
36	readConcern    *readconcern.ReadConcern
37	readPreference *readpref.ReadPref
38	selector       description.ServerSelector
39	retry          *driver.RetryMode
40	result         CountResult
41}
42
43type CountResult struct {
44	// The number of documents found
45	N int64
46}
47
48func buildCountResult(response bsoncore.Document, srvr driver.Server) (CountResult, error) {
49	elements, err := response.Elements()
50	if err != nil {
51		return CountResult{}, err
52	}
53	cr := CountResult{}
54	for _, element := range elements {
55		switch element.Key() {
56		case "n":
57			var ok bool
58			cr.N, ok = element.Value().AsInt64OK()
59			if !ok {
60				err = fmt.Errorf("response field 'n' is type int64, but received BSON type %s", element.Value().Type)
61			}
62		}
63	}
64	return cr, nil
65}
66
67// NewCount constructs and returns a new Count.
68func NewCount() *Count {
69	return &Count{}
70}
71
72// Result returns the result of executing this operation.
73func (c *Count) Result() CountResult { return c.result }
74
75func (c *Count) processResponse(response bsoncore.Document, srvr driver.Server, desc description.Server) error {
76	var err error
77	c.result, err = buildCountResult(response, srvr)
78	return err
79}
80
81// Execute runs this operations and returns an error if the operaiton did not execute successfully.
82func (c *Count) Execute(ctx context.Context) error {
83	if c.deployment == nil {
84		return errors.New("the Count operation must have a Deployment set before Execute can be called")
85	}
86
87	return driver.Operation{
88		CommandFn:         c.command,
89		ProcessResponseFn: c.processResponse,
90		RetryMode:         c.retry,
91		Type:              driver.Read,
92		Client:            c.session,
93		Clock:             c.clock,
94		CommandMonitor:    c.monitor,
95		Crypt:             c.crypt,
96		Database:          c.database,
97		Deployment:        c.deployment,
98		ReadConcern:       c.readConcern,
99		ReadPreference:    c.readPreference,
100		Selector:          c.selector,
101	}.Execute(ctx, nil)
102
103}
104
105func (c *Count) command(dst []byte, desc description.SelectedServer) ([]byte, error) {
106	dst = bsoncore.AppendStringElement(dst, "count", c.collection)
107	if c.maxTimeMS != nil {
108		dst = bsoncore.AppendInt64Element(dst, "maxTimeMS", *c.maxTimeMS)
109	}
110	if c.query != nil {
111		dst = bsoncore.AppendDocumentElement(dst, "query", c.query)
112	}
113	return dst, nil
114}
115
116// MaxTimeMS specifies the maximum amount of time to allow the query to run.
117func (c *Count) MaxTimeMS(maxTimeMS int64) *Count {
118	if c == nil {
119		c = new(Count)
120	}
121
122	c.maxTimeMS = &maxTimeMS
123	return c
124}
125
126// Query determines what results are returned from find.
127func (c *Count) Query(query bsoncore.Document) *Count {
128	if c == nil {
129		c = new(Count)
130	}
131
132	c.query = query
133	return c
134}
135
136// Session sets the session for this operation.
137func (c *Count) Session(session *session.Client) *Count {
138	if c == nil {
139		c = new(Count)
140	}
141
142	c.session = session
143	return c
144}
145
146// ClusterClock sets the cluster clock for this operation.
147func (c *Count) ClusterClock(clock *session.ClusterClock) *Count {
148	if c == nil {
149		c = new(Count)
150	}
151
152	c.clock = clock
153	return c
154}
155
156// Collection sets the collection that this command will run against.
157func (c *Count) Collection(collection string) *Count {
158	if c == nil {
159		c = new(Count)
160	}
161
162	c.collection = collection
163	return c
164}
165
166// CommandMonitor sets the monitor to use for APM events.
167func (c *Count) CommandMonitor(monitor *event.CommandMonitor) *Count {
168	if c == nil {
169		c = new(Count)
170	}
171
172	c.monitor = monitor
173	return c
174}
175
176// Crypt sets the Crypt object to use for automatic encryption and decryption.
177func (c *Count) Crypt(crypt *driver.Crypt) *Count {
178	if c == nil {
179		c = new(Count)
180	}
181
182	c.crypt = crypt
183	return c
184}
185
186// Database sets the database to run this operation against.
187func (c *Count) Database(database string) *Count {
188	if c == nil {
189		c = new(Count)
190	}
191
192	c.database = database
193	return c
194}
195
196// Deployment sets the deployment to use for this operation.
197func (c *Count) Deployment(deployment driver.Deployment) *Count {
198	if c == nil {
199		c = new(Count)
200	}
201
202	c.deployment = deployment
203	return c
204}
205
206// ReadConcern specifies the read concern for this operation.
207func (c *Count) ReadConcern(readConcern *readconcern.ReadConcern) *Count {
208	if c == nil {
209		c = new(Count)
210	}
211
212	c.readConcern = readConcern
213	return c
214}
215
216// ReadPreference set the read prefernce used with this operation.
217func (c *Count) ReadPreference(readPreference *readpref.ReadPref) *Count {
218	if c == nil {
219		c = new(Count)
220	}
221
222	c.readPreference = readPreference
223	return c
224}
225
226// ServerSelector sets the selector used to retrieve a server.
227func (c *Count) ServerSelector(selector description.ServerSelector) *Count {
228	if c == nil {
229		c = new(Count)
230	}
231
232	c.selector = selector
233	return c
234}
235
236// Retry enables retryable mode for this operation. Retries are handled automatically in driver.Operation.Execute based
237// on how the operation is set.
238func (c *Count) Retry(retry driver.RetryMode) *Count {
239	if c == nil {
240		c = new(Count)
241	}
242
243	c.retry = &retry
244	return c
245}
246