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/description"
18	"go.mongodb.org/mongo-driver/mongo/writeconcern"
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/session"
22)
23
24// Delete performs a delete operation
25type Delete struct {
26	deletes      []bsoncore.Document
27	ordered      *bool
28	session      *session.Client
29	clock        *session.ClusterClock
30	collection   string
31	monitor      *event.CommandMonitor
32	crypt        *driver.Crypt
33	database     string
34	deployment   driver.Deployment
35	selector     description.ServerSelector
36	writeConcern *writeconcern.WriteConcern
37	retry        *driver.RetryMode
38	hint         *bool
39	result       DeleteResult
40}
41
42type DeleteResult struct {
43	// Number of documents successfully deleted.
44	N int32
45}
46
47func buildDeleteResult(response bsoncore.Document, srvr driver.Server) (DeleteResult, error) {
48	elements, err := response.Elements()
49	if err != nil {
50		return DeleteResult{}, err
51	}
52	dr := DeleteResult{}
53	for _, element := range elements {
54		switch element.Key() {
55		case "n":
56			var ok bool
57			dr.N, ok = element.Value().AsInt32OK()
58			if !ok {
59				err = fmt.Errorf("response field 'n' is type int32, but received BSON type %s", element.Value().Type)
60			}
61		}
62	}
63	return dr, nil
64}
65
66// NewDelete constructs and returns a new Delete.
67func NewDelete(deletes ...bsoncore.Document) *Delete {
68	return &Delete{
69		deletes: deletes,
70	}
71}
72
73// Result returns the result of executing this operation.
74func (d *Delete) Result() DeleteResult { return d.result }
75
76func (d *Delete) processResponse(response bsoncore.Document, srvr driver.Server, desc description.Server, _ int) error {
77	dr, err := buildDeleteResult(response, srvr)
78	d.result.N += dr.N
79	return err
80}
81
82// Execute runs this operations and returns an error if the operaiton did not execute successfully.
83func (d *Delete) Execute(ctx context.Context) error {
84	if d.deployment == nil {
85		return errors.New("the Delete operation must have a Deployment set before Execute can be called")
86	}
87	batches := &driver.Batches{
88		Identifier: "deletes",
89		Documents:  d.deletes,
90		Ordered:    d.ordered,
91	}
92
93	return driver.Operation{
94		CommandFn:         d.command,
95		ProcessResponseFn: d.processResponse,
96		Batches:           batches,
97		RetryMode:         d.retry,
98		Type:              driver.Write,
99		Client:            d.session,
100		Clock:             d.clock,
101		CommandMonitor:    d.monitor,
102		Crypt:             d.crypt,
103		Database:          d.database,
104		Deployment:        d.deployment,
105		Selector:          d.selector,
106		WriteConcern:      d.writeConcern,
107	}.Execute(ctx, nil)
108
109}
110
111func (d *Delete) command(dst []byte, desc description.SelectedServer) ([]byte, error) {
112	dst = bsoncore.AppendStringElement(dst, "delete", d.collection)
113	if d.ordered != nil {
114		dst = bsoncore.AppendBooleanElement(dst, "ordered", *d.ordered)
115	}
116	if d.hint != nil && *d.hint {
117		if desc.WireVersion == nil || !desc.WireVersion.Includes(5) {
118			return nil, errors.New("the 'hint' command parameter requires a minimum server wire version of 5")
119		}
120		if !d.writeConcern.Acknowledged() {
121			return nil, errUnacknowledgedHint
122		}
123	}
124	return dst, nil
125}
126
127// Deletes adds documents to this operation that will be used to determine what documents to delete when this operation
128// is executed. These documents should have the form {q: <query>, limit: <integer limit>, collation: <document>}. The
129// collation field is optional. If limit is 0, there will be no limit on the number of documents deleted.
130func (d *Delete) Deletes(deletes ...bsoncore.Document) *Delete {
131	if d == nil {
132		d = new(Delete)
133	}
134
135	d.deletes = deletes
136	return d
137}
138
139// Ordered sets ordered. If true, when a write fails, the operation will return the error, when
140// false write failures do not stop execution of the operation.
141func (d *Delete) Ordered(ordered bool) *Delete {
142	if d == nil {
143		d = new(Delete)
144	}
145
146	d.ordered = &ordered
147	return d
148}
149
150// Session sets the session for this operation.
151func (d *Delete) Session(session *session.Client) *Delete {
152	if d == nil {
153		d = new(Delete)
154	}
155
156	d.session = session
157	return d
158}
159
160// ClusterClock sets the cluster clock for this operation.
161func (d *Delete) ClusterClock(clock *session.ClusterClock) *Delete {
162	if d == nil {
163		d = new(Delete)
164	}
165
166	d.clock = clock
167	return d
168}
169
170// Collection sets the collection that this command will run against.
171func (d *Delete) Collection(collection string) *Delete {
172	if d == nil {
173		d = new(Delete)
174	}
175
176	d.collection = collection
177	return d
178}
179
180// CommandMonitor sets the monitor to use for APM events.
181func (d *Delete) CommandMonitor(monitor *event.CommandMonitor) *Delete {
182	if d == nil {
183		d = new(Delete)
184	}
185
186	d.monitor = monitor
187	return d
188}
189
190// Crypt sets the Crypt object to use for automatic encryption and decryption.
191func (d *Delete) Crypt(crypt *driver.Crypt) *Delete {
192	if d == nil {
193		d = new(Delete)
194	}
195
196	d.crypt = crypt
197	return d
198}
199
200// Database sets the database to run this operation against.
201func (d *Delete) Database(database string) *Delete {
202	if d == nil {
203		d = new(Delete)
204	}
205
206	d.database = database
207	return d
208}
209
210// Deployment sets the deployment to use for this operation.
211func (d *Delete) Deployment(deployment driver.Deployment) *Delete {
212	if d == nil {
213		d = new(Delete)
214	}
215
216	d.deployment = deployment
217	return d
218}
219
220// ServerSelector sets the selector used to retrieve a server.
221func (d *Delete) ServerSelector(selector description.ServerSelector) *Delete {
222	if d == nil {
223		d = new(Delete)
224	}
225
226	d.selector = selector
227	return d
228}
229
230// WriteConcern sets the write concern for this operation.
231func (d *Delete) WriteConcern(writeConcern *writeconcern.WriteConcern) *Delete {
232	if d == nil {
233		d = new(Delete)
234	}
235
236	d.writeConcern = writeConcern
237	return d
238}
239
240// Retry enables retryable mode for this operation. Retries are handled automatically in driver.Operation.Execute based
241// on how the operation is set.
242func (d *Delete) Retry(retry driver.RetryMode) *Delete {
243	if d == nil {
244		d = new(Delete)
245	}
246
247	d.retry = &retry
248	return d
249}
250
251// Hint is a flag to indicate that the update document contains a hint. Hint is only supported by
252// servers >= 4.4. Older servers >= 3.4 will report an error for using the hint option. For servers <
253// 3.4, the driver will return an error if the hint option is used.
254func (d *Delete) Hint(hint bool) *Delete {
255	if d == nil {
256		d = new(Delete)
257	}
258
259	d.hint = &hint
260	return d
261}
262