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/writeconcern"
18	"go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
19	"go.mongodb.org/mongo-driver/x/mongo/driver"
20	"go.mongodb.org/mongo-driver/x/mongo/driver/description"
21	"go.mongodb.org/mongo-driver/x/mongo/driver/session"
22)
23
24// Insert performs an insert operation.
25type Insert struct {
26	bypassDocumentValidation *bool
27	documents                []bsoncore.Document
28	ordered                  *bool
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	selector                 description.ServerSelector
37	writeConcern             *writeconcern.WriteConcern
38	retry                    *driver.RetryMode
39	result                   InsertResult
40}
41
42type InsertResult struct {
43	// Number of documents successfully inserted.
44	N int32
45}
46
47func buildInsertResult(response bsoncore.Document, srvr driver.Server) (InsertResult, error) {
48	elements, err := response.Elements()
49	if err != nil {
50		return InsertResult{}, err
51	}
52	ir := InsertResult{}
53	for _, element := range elements {
54		switch element.Key() {
55		case "n":
56			var ok bool
57			ir.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 ir, nil
64}
65
66// NewInsert constructs and returns a new Insert.
67func NewInsert(documents ...bsoncore.Document) *Insert {
68	return &Insert{
69		documents: documents,
70	}
71}
72
73// Result returns the result of executing this operation.
74func (i *Insert) Result() InsertResult { return i.result }
75
76func (i *Insert) processResponse(response bsoncore.Document, srvr driver.Server, desc description.Server, insert int) error {
77	ir, err := buildInsertResult(response, srvr)
78	i.result.N += ir.N
79	return err
80}
81
82// Execute runs this operations and returns an error if the operaiton did not execute successfully.
83func (i *Insert) Execute(ctx context.Context) error {
84	if i.deployment == nil {
85		return errors.New("the Insert operation must have a Deployment set before Execute can be called")
86	}
87	batches := &driver.Batches{
88		Identifier: "documents",
89		Documents:  i.documents,
90		Ordered:    i.ordered,
91	}
92
93	return driver.Operation{
94		CommandFn:         i.command,
95		ProcessResponseFn: i.processResponse,
96		Batches:           batches,
97		RetryMode:         i.retry,
98		Type:              driver.Write,
99		Client:            i.session,
100		Clock:             i.clock,
101		CommandMonitor:    i.monitor,
102		Crypt:             i.crypt,
103		Database:          i.database,
104		Deployment:        i.deployment,
105		Selector:          i.selector,
106		WriteConcern:      i.writeConcern,
107	}.Execute(ctx, nil)
108
109}
110
111func (i *Insert) command(dst []byte, desc description.SelectedServer) ([]byte, error) {
112	dst = bsoncore.AppendStringElement(dst, "insert", i.collection)
113	if i.bypassDocumentValidation != nil && (desc.WireVersion != nil && desc.WireVersion.Includes(4)) {
114		dst = bsoncore.AppendBooleanElement(dst, "bypassDocumentValidation", *i.bypassDocumentValidation)
115	}
116	if i.ordered != nil {
117		dst = bsoncore.AppendBooleanElement(dst, "ordered", *i.ordered)
118	}
119	return dst, nil
120}
121
122// BypassDocumentValidation allows the operation to opt-out of document level validation. Valid
123// for server versions >= 3.2. For servers < 3.2, this setting is ignored.
124func (i *Insert) BypassDocumentValidation(bypassDocumentValidation bool) *Insert {
125	if i == nil {
126		i = new(Insert)
127	}
128
129	i.bypassDocumentValidation = &bypassDocumentValidation
130	return i
131}
132
133// Documents adds documents to this operation that will be inserted when this operation is
134// executed.
135func (i *Insert) Documents(documents ...bsoncore.Document) *Insert {
136	if i == nil {
137		i = new(Insert)
138	}
139
140	i.documents = documents
141	return i
142}
143
144// Ordered sets ordered. If true, when a write fails, the operation will return the error, when
145// false write failures do not stop execution of the operation.
146func (i *Insert) Ordered(ordered bool) *Insert {
147	if i == nil {
148		i = new(Insert)
149	}
150
151	i.ordered = &ordered
152	return i
153}
154
155// Session sets the session for this operation.
156func (i *Insert) Session(session *session.Client) *Insert {
157	if i == nil {
158		i = new(Insert)
159	}
160
161	i.session = session
162	return i
163}
164
165// ClusterClock sets the cluster clock for this operation.
166func (i *Insert) ClusterClock(clock *session.ClusterClock) *Insert {
167	if i == nil {
168		i = new(Insert)
169	}
170
171	i.clock = clock
172	return i
173}
174
175// Collection sets the collection that this command will run against.
176func (i *Insert) Collection(collection string) *Insert {
177	if i == nil {
178		i = new(Insert)
179	}
180
181	i.collection = collection
182	return i
183}
184
185// CommandMonitor sets the monitor to use for APM events.
186func (i *Insert) CommandMonitor(monitor *event.CommandMonitor) *Insert {
187	if i == nil {
188		i = new(Insert)
189	}
190
191	i.monitor = monitor
192	return i
193}
194
195// Crypt sets the Crypt object to use for automatic encryption and decryption.
196func (i *Insert) Crypt(crypt *driver.Crypt) *Insert {
197	if i == nil {
198		i = new(Insert)
199	}
200
201	i.crypt = crypt
202	return i
203}
204
205// Database sets the database to run this operation against.
206func (i *Insert) Database(database string) *Insert {
207	if i == nil {
208		i = new(Insert)
209	}
210
211	i.database = database
212	return i
213}
214
215// Deployment sets the deployment to use for this operation.
216func (i *Insert) Deployment(deployment driver.Deployment) *Insert {
217	if i == nil {
218		i = new(Insert)
219	}
220
221	i.deployment = deployment
222	return i
223}
224
225// ServerSelector sets the selector used to retrieve a server.
226func (i *Insert) ServerSelector(selector description.ServerSelector) *Insert {
227	if i == nil {
228		i = new(Insert)
229	}
230
231	i.selector = selector
232	return i
233}
234
235// WriteConcern sets the write concern for this operation.
236func (i *Insert) WriteConcern(writeConcern *writeconcern.WriteConcern) *Insert {
237	if i == nil {
238		i = new(Insert)
239	}
240
241	i.writeConcern = writeConcern
242	return i
243}
244
245// Retry enables retryable mode for this operation. Retries are handled automatically in driver.Operation.Execute based
246// on how the operation is set.
247func (i *Insert) Retry(retry driver.RetryMode) *Insert {
248	if i == nil {
249		i = new(Insert)
250	}
251
252	i.retry = &retry
253	return i
254}
255