1// 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 mongo
8
9import (
10	"go.mongodb.org/mongo-driver/mongo/options"
11)
12
13// WriteModel is an interface implemented by models that can be used in a BulkWrite operation. Each WriteModel
14// represents a write.
15//
16// This interface is implemented by InsertOneModel, DeleteOneModel, DeleteManyModel, ReplaceOneModel, UpdateOneModel,
17// and UpdateManyModel. Custom implementations of this interface must not be used.
18type WriteModel interface {
19	writeModel()
20}
21
22// InsertOneModel is used to insert a single document in a BulkWrite operation.
23type InsertOneModel struct {
24	Document interface{}
25}
26
27// NewInsertOneModel creates a new InsertOneModel.
28func NewInsertOneModel() *InsertOneModel {
29	return &InsertOneModel{}
30}
31
32// SetDocument specifies the document to be inserted. The document cannot be nil. If it does not have an _id field when
33// transformed into BSON, one will be added automatically to the marshalled document. The original document will not be
34// modified.
35func (iom *InsertOneModel) SetDocument(doc interface{}) *InsertOneModel {
36	iom.Document = doc
37	return iom
38}
39
40func (*InsertOneModel) writeModel() {}
41
42// DeleteOneModel is used to delete at most one document in a BulkWriteOperation.
43type DeleteOneModel struct {
44	Filter    interface{}
45	Collation *options.Collation
46	Hint      interface{}
47}
48
49// NewDeleteOneModel creates a new DeleteOneModel.
50func NewDeleteOneModel() *DeleteOneModel {
51	return &DeleteOneModel{}
52}
53
54// SetFilter specifies a filter to use to select the document to delete. The filter must be a document containing query
55// operators. It cannot be nil. If the filter matches multiple documents, one will be selected from the matching
56// documents.
57func (dom *DeleteOneModel) SetFilter(filter interface{}) *DeleteOneModel {
58	dom.Filter = filter
59	return dom
60}
61
62// SetCollation specifies a collation to use for string comparisons. The default is nil, meaning no collation will be
63// used.
64func (dom *DeleteOneModel) SetCollation(collation *options.Collation) *DeleteOneModel {
65	dom.Collation = collation
66	return dom
67}
68
69// SetHint specifies the index to use for the operation. This should either be the index name as a string or the index
70// specification as a document. This option is only valid for MongoDB versions >= 4.4. Server versions >= 3.4 will
71// return an error if this option is specified. For server versions < 3.4, the driver will return a client-side error if
72// this option is specified. The driver will return an error if this option is specified during an unacknowledged write
73// operation. The driver will return an error if the hint parameter is a multi-key map. The default value is nil, which
74// means that no hint will be sent.
75func (dom *DeleteOneModel) SetHint(hint interface{}) *DeleteOneModel {
76	dom.Hint = hint
77	return dom
78}
79
80func (*DeleteOneModel) writeModel() {}
81
82// DeleteManyModel is used to delete multiple documents in a BulkWrite operation.
83type DeleteManyModel struct {
84	Filter    interface{}
85	Collation *options.Collation
86	Hint      interface{}
87}
88
89// NewDeleteManyModel creates a new DeleteManyModel.
90func NewDeleteManyModel() *DeleteManyModel {
91	return &DeleteManyModel{}
92}
93
94// SetFilter specifies a filter to use to select documents to delete. The filter must be a document containing query
95// operators. It cannot be nil.
96func (dmm *DeleteManyModel) SetFilter(filter interface{}) *DeleteManyModel {
97	dmm.Filter = filter
98	return dmm
99}
100
101// SetCollation specifies a collation to use for string comparisons. The default is nil, meaning no collation will be
102// used.
103func (dmm *DeleteManyModel) SetCollation(collation *options.Collation) *DeleteManyModel {
104	dmm.Collation = collation
105	return dmm
106}
107
108// SetHint specifies the index to use for the operation. This should either be the index name as a string or the index
109// specification as a document. This option is only valid for MongoDB versions >= 4.4. Server versions >= 3.4 will
110// return an error if this option is specified. For server versions < 3.4, the driver will return a client-side error if
111// this option is specified. The driver will return an error if this option is specified during an unacknowledged write
112// operation. The driver will return an error if the hint parameter is a multi-key map. The default value is nil, which
113// means that no hint will be sent.
114func (dmm *DeleteManyModel) SetHint(hint interface{}) *DeleteManyModel {
115	dmm.Hint = hint
116	return dmm
117}
118
119func (*DeleteManyModel) writeModel() {}
120
121// ReplaceOneModel is used to replace at most one document in a BulkWrite operation.
122type ReplaceOneModel struct {
123	Collation   *options.Collation
124	Upsert      *bool
125	Filter      interface{}
126	Replacement interface{}
127	Hint        interface{}
128}
129
130// NewReplaceOneModel creates a new ReplaceOneModel.
131func NewReplaceOneModel() *ReplaceOneModel {
132	return &ReplaceOneModel{}
133}
134
135// SetHint specifies the index to use for the operation. This should either be the index name as a string or the index
136// specification as a document. This option is only valid for MongoDB versions >= 4.2. Server versions >= 3.4 will
137// return an error if this option is specified. For server versions < 3.4, the driver will return a client-side error if
138// this option is specified. The driver will return an error if this option is specified during an unacknowledged write
139// operation. The driver will return an error if the hint parameter is a multi-key map. The default value is nil, which
140// means that no hint will be sent.
141func (rom *ReplaceOneModel) SetHint(hint interface{}) *ReplaceOneModel {
142	rom.Hint = hint
143	return rom
144}
145
146// SetFilter specifies a filter to use to select the document to replace. The filter must be a document containing query
147// operators. It cannot be nil. If the filter matches multiple documents, one will be selected from the matching
148// documents.
149func (rom *ReplaceOneModel) SetFilter(filter interface{}) *ReplaceOneModel {
150	rom.Filter = filter
151	return rom
152}
153
154// SetReplacement specifies a document that will be used to replace the selected document. It cannot be nil and cannot
155// contain any update operators (https://docs.mongodb.com/manual/reference/operator/update/).
156func (rom *ReplaceOneModel) SetReplacement(rep interface{}) *ReplaceOneModel {
157	rom.Replacement = rep
158	return rom
159}
160
161// SetCollation specifies a collation to use for string comparisons. The default is nil, meaning no collation will be
162// used.
163func (rom *ReplaceOneModel) SetCollation(collation *options.Collation) *ReplaceOneModel {
164	rom.Collation = collation
165	return rom
166}
167
168// SetUpsert specifies whether or not the replacement document should be inserted if no document matching the filter is
169// found. If an upsert is performed, the _id of the upserted document can be retrieved from the UpsertedIDs field of the
170// BulkWriteResult.
171func (rom *ReplaceOneModel) SetUpsert(upsert bool) *ReplaceOneModel {
172	rom.Upsert = &upsert
173	return rom
174}
175
176func (*ReplaceOneModel) writeModel() {}
177
178// UpdateOneModel is used to update at most one document in a BulkWrite operation.
179type UpdateOneModel struct {
180	Collation    *options.Collation
181	Upsert       *bool
182	Filter       interface{}
183	Update       interface{}
184	ArrayFilters *options.ArrayFilters
185	Hint         interface{}
186}
187
188// NewUpdateOneModel creates a new UpdateOneModel.
189func NewUpdateOneModel() *UpdateOneModel {
190	return &UpdateOneModel{}
191}
192
193// SetHint specifies the index to use for the operation. This should either be the index name as a string or the index
194// specification as a document. This option is only valid for MongoDB versions >= 4.2. Server versions >= 3.4 will
195// return an error if this option is specified. For server versions < 3.4, the driver will return a client-side error if
196// this option is specified. The driver will return an error if this option is specified during an unacknowledged write
197// operation. The driver will return an error if the hint parameter is a multi-key map. The default value is nil, which
198// means that no hint will be sent.
199func (uom *UpdateOneModel) SetHint(hint interface{}) *UpdateOneModel {
200	uom.Hint = hint
201	return uom
202}
203
204// SetFilter specifies a filter to use to select the document to update. The filter must be a document containing query
205// operators. It cannot be nil. If the filter matches multiple documents, one will be selected from the matching
206// documents.
207func (uom *UpdateOneModel) SetFilter(filter interface{}) *UpdateOneModel {
208	uom.Filter = filter
209	return uom
210}
211
212// SetUpdate specifies the modifications to be made to the selected document. The value must be a document containing
213// update operators (https://docs.mongodb.com/manual/reference/operator/update/). It cannot be nil or empty.
214func (uom *UpdateOneModel) SetUpdate(update interface{}) *UpdateOneModel {
215	uom.Update = update
216	return uom
217}
218
219// SetArrayFilters specifies a set of filters to determine which elements should be modified when updating an array
220// field.
221func (uom *UpdateOneModel) SetArrayFilters(filters options.ArrayFilters) *UpdateOneModel {
222	uom.ArrayFilters = &filters
223	return uom
224}
225
226// SetCollation specifies a collation to use for string comparisons. The default is nil, meaning no collation will be
227// used.
228func (uom *UpdateOneModel) SetCollation(collation *options.Collation) *UpdateOneModel {
229	uom.Collation = collation
230	return uom
231}
232
233// SetUpsert specifies whether or not a new document should be inserted if no document matching the filter is found. If
234// an upsert is performed, the _id of the upserted document can be retrieved from the UpsertedIDs field of the
235// BulkWriteResult.
236func (uom *UpdateOneModel) SetUpsert(upsert bool) *UpdateOneModel {
237	uom.Upsert = &upsert
238	return uom
239}
240
241func (*UpdateOneModel) writeModel() {}
242
243// UpdateManyModel is used to update multiple documents in a BulkWrite operation.
244type UpdateManyModel struct {
245	Collation    *options.Collation
246	Upsert       *bool
247	Filter       interface{}
248	Update       interface{}
249	ArrayFilters *options.ArrayFilters
250	Hint         interface{}
251}
252
253// NewUpdateManyModel creates a new UpdateManyModel.
254func NewUpdateManyModel() *UpdateManyModel {
255	return &UpdateManyModel{}
256}
257
258// SetHint specifies the index to use for the operation. This should either be the index name as a string or the index
259// specification as a document. This option is only valid for MongoDB versions >= 4.2. Server versions >= 3.4 will
260// return an error if this option is specified. For server versions < 3.4, the driver will return a client-side error if
261// this option is specified. The driver will return an error if this option is specified during an unacknowledged write
262// operation. The driver will return an error if the hint parameter is a multi-key map. The default value is nil, which
263// means that no hint will be sent.
264func (umm *UpdateManyModel) SetHint(hint interface{}) *UpdateManyModel {
265	umm.Hint = hint
266	return umm
267}
268
269// SetFilter specifies a filter to use to select documents to update. The filter must be a document containing query
270// operators. It cannot be nil.
271func (umm *UpdateManyModel) SetFilter(filter interface{}) *UpdateManyModel {
272	umm.Filter = filter
273	return umm
274}
275
276// SetUpdate specifies the modifications to be made to the selected documents. The value must be a document containing
277// update operators (https://docs.mongodb.com/manual/reference/operator/update/). It cannot be nil or empty.
278func (umm *UpdateManyModel) SetUpdate(update interface{}) *UpdateManyModel {
279	umm.Update = update
280	return umm
281}
282
283// SetArrayFilters specifies a set of filters to determine which elements should be modified when updating an array
284// field.
285func (umm *UpdateManyModel) SetArrayFilters(filters options.ArrayFilters) *UpdateManyModel {
286	umm.ArrayFilters = &filters
287	return umm
288}
289
290// SetCollation specifies a collation to use for string comparisons. The default is nil, meaning no collation will be
291// used.
292func (umm *UpdateManyModel) SetCollation(collation *options.Collation) *UpdateManyModel {
293	umm.Collation = collation
294	return umm
295}
296
297// SetUpsert specifies whether or not a new document should be inserted if no document matching the filter is found. If
298// an upsert is performed, the _id of the upserted document can be retrieved from the UpsertedIDs field of the
299// BulkWriteResult.
300func (umm *UpdateManyModel) SetUpsert(upsert bool) *UpdateManyModel {
301	umm.Upsert = &upsert
302	return umm
303}
304
305func (*UpdateManyModel) writeModel() {}
306