Don Newton | 379ae25 | 2019-04-01 12:17:06 -0400 | [diff] [blame^] | 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 | |
| 7 | package mongo |
| 8 | |
| 9 | import ( |
| 10 | "github.com/mongodb/mongo-go-driver/mongo/options" |
| 11 | "github.com/mongodb/mongo-go-driver/x/mongo/driver" |
| 12 | ) |
| 13 | |
| 14 | // WriteModel is the interface satisfied by all models for bulk writes. |
| 15 | type WriteModel interface { |
| 16 | convertModel() driver.WriteModel |
| 17 | } |
| 18 | |
| 19 | // InsertOneModel is the write model for insert operations. |
| 20 | type InsertOneModel struct { |
| 21 | Document interface{} |
| 22 | } |
| 23 | |
| 24 | // NewInsertOneModel creates a new InsertOneModel. |
| 25 | func NewInsertOneModel() *InsertOneModel { |
| 26 | return &InsertOneModel{} |
| 27 | } |
| 28 | |
| 29 | // SetDocument sets the BSON document for the InsertOneModel. |
| 30 | func (iom *InsertOneModel) SetDocument(doc interface{}) *InsertOneModel { |
| 31 | iom.Document = doc |
| 32 | return iom |
| 33 | } |
| 34 | |
| 35 | func (iom *InsertOneModel) convertModel() driver.WriteModel { |
| 36 | return driver.InsertOneModel{ |
| 37 | Document: iom.Document, |
| 38 | } |
| 39 | } |
| 40 | |
| 41 | // DeleteOneModel is the write model for delete operations. |
| 42 | type DeleteOneModel struct { |
| 43 | Filter interface{} |
| 44 | Collation *options.Collation |
| 45 | } |
| 46 | |
| 47 | // NewDeleteOneModel creates a new DeleteOneModel. |
| 48 | func NewDeleteOneModel() *DeleteOneModel { |
| 49 | return &DeleteOneModel{} |
| 50 | } |
| 51 | |
| 52 | // SetFilter sets the filter for the DeleteOneModel. |
| 53 | func (dom *DeleteOneModel) SetFilter(filter interface{}) *DeleteOneModel { |
| 54 | dom.Filter = filter |
| 55 | return dom |
| 56 | } |
| 57 | |
| 58 | // SetCollation sets the collation for the DeleteOneModel. |
| 59 | func (dom *DeleteOneModel) SetCollation(collation *options.Collation) *DeleteOneModel { |
| 60 | dom.Collation = collation |
| 61 | return dom |
| 62 | } |
| 63 | |
| 64 | func (dom *DeleteOneModel) convertModel() driver.WriteModel { |
| 65 | return driver.DeleteOneModel{ |
| 66 | Collation: dom.Collation, |
| 67 | Filter: dom.Filter, |
| 68 | } |
| 69 | } |
| 70 | |
| 71 | // DeleteManyModel is the write model for deleteMany operations. |
| 72 | type DeleteManyModel struct { |
| 73 | Filter interface{} |
| 74 | Collation *options.Collation |
| 75 | } |
| 76 | |
| 77 | // NewDeleteManyModel creates a new DeleteManyModel. |
| 78 | func NewDeleteManyModel() *DeleteManyModel { |
| 79 | return &DeleteManyModel{} |
| 80 | } |
| 81 | |
| 82 | // SetFilter sets the filter for the DeleteManyModel. |
| 83 | func (dmm *DeleteManyModel) SetFilter(filter interface{}) *DeleteManyModel { |
| 84 | dmm.Filter = filter |
| 85 | return dmm |
| 86 | } |
| 87 | |
| 88 | // SetCollation sets the collation for the DeleteManyModel. |
| 89 | func (dmm *DeleteManyModel) SetCollation(collation *options.Collation) *DeleteManyModel { |
| 90 | dmm.Collation = collation |
| 91 | return dmm |
| 92 | } |
| 93 | |
| 94 | func (dmm *DeleteManyModel) convertModel() driver.WriteModel { |
| 95 | return driver.DeleteManyModel{ |
| 96 | Collation: dmm.Collation, |
| 97 | Filter: dmm.Filter, |
| 98 | } |
| 99 | } |
| 100 | |
| 101 | // ReplaceOneModel is the write model for replace operations. |
| 102 | type ReplaceOneModel struct { |
| 103 | Collation *options.Collation |
| 104 | Upsert *bool |
| 105 | Filter interface{} |
| 106 | Replacement interface{} |
| 107 | } |
| 108 | |
| 109 | // NewReplaceOneModel creates a new ReplaceOneModel. |
| 110 | func NewReplaceOneModel() *ReplaceOneModel { |
| 111 | return &ReplaceOneModel{} |
| 112 | } |
| 113 | |
| 114 | // SetFilter sets the filter for the ReplaceOneModel. |
| 115 | func (rom *ReplaceOneModel) SetFilter(filter interface{}) *ReplaceOneModel { |
| 116 | rom.Filter = filter |
| 117 | return rom |
| 118 | } |
| 119 | |
| 120 | // SetReplacement sets the replacement document for the ReplaceOneModel. |
| 121 | func (rom *ReplaceOneModel) SetReplacement(rep interface{}) *ReplaceOneModel { |
| 122 | rom.Replacement = rep |
| 123 | return rom |
| 124 | } |
| 125 | |
| 126 | // SetCollation sets the collation for the ReplaceOneModel. |
| 127 | func (rom *ReplaceOneModel) SetCollation(collation *options.Collation) *ReplaceOneModel { |
| 128 | rom.Collation = collation |
| 129 | return rom |
| 130 | } |
| 131 | |
| 132 | // SetUpsert specifies if a new document should be created if no document matches the query. |
| 133 | func (rom *ReplaceOneModel) SetUpsert(upsert bool) *ReplaceOneModel { |
| 134 | rom.Upsert = &upsert |
| 135 | return rom |
| 136 | } |
| 137 | |
| 138 | func (rom *ReplaceOneModel) convertModel() driver.WriteModel { |
| 139 | um := driver.UpdateModel{ |
| 140 | Collation: rom.Collation, |
| 141 | } |
| 142 | if rom.Upsert != nil { |
| 143 | um.Upsert = *rom.Upsert |
| 144 | um.UpsertSet = true |
| 145 | } |
| 146 | |
| 147 | return driver.ReplaceOneModel{ |
| 148 | UpdateModel: um, |
| 149 | Filter: rom.Filter, |
| 150 | Replacement: rom.Replacement, |
| 151 | } |
| 152 | } |
| 153 | |
| 154 | // UpdateOneModel is the write model for update operations. |
| 155 | type UpdateOneModel struct { |
| 156 | Collation *options.Collation |
| 157 | Upsert *bool |
| 158 | Filter interface{} |
| 159 | Update interface{} |
| 160 | ArrayFilters *options.ArrayFilters |
| 161 | } |
| 162 | |
| 163 | // NewUpdateOneModel creates a new UpdateOneModel. |
| 164 | func NewUpdateOneModel() *UpdateOneModel { |
| 165 | return &UpdateOneModel{} |
| 166 | } |
| 167 | |
| 168 | // SetFilter sets the filter for the UpdateOneModel. |
| 169 | func (uom *UpdateOneModel) SetFilter(filter interface{}) *UpdateOneModel { |
| 170 | uom.Filter = filter |
| 171 | return uom |
| 172 | } |
| 173 | |
| 174 | // SetUpdate sets the update document for the UpdateOneModel. |
| 175 | func (uom *UpdateOneModel) SetUpdate(update interface{}) *UpdateOneModel { |
| 176 | uom.Update = update |
| 177 | return uom |
| 178 | } |
| 179 | |
| 180 | // SetArrayFilters specifies a set of filters specifying to which array elements an update should apply. |
| 181 | func (uom *UpdateOneModel) SetArrayFilters(filters options.ArrayFilters) *UpdateOneModel { |
| 182 | uom.ArrayFilters = &filters |
| 183 | return uom |
| 184 | } |
| 185 | |
| 186 | // SetCollation sets the collation for the UpdateOneModel. |
| 187 | func (uom *UpdateOneModel) SetCollation(collation *options.Collation) *UpdateOneModel { |
| 188 | uom.Collation = collation |
| 189 | return uom |
| 190 | } |
| 191 | |
| 192 | // SetUpsert specifies if a new document should be created if no document matches the query. |
| 193 | func (uom *UpdateOneModel) SetUpsert(upsert bool) *UpdateOneModel { |
| 194 | uom.Upsert = &upsert |
| 195 | return uom |
| 196 | } |
| 197 | |
| 198 | func (uom *UpdateOneModel) convertModel() driver.WriteModel { |
| 199 | um := driver.UpdateModel{ |
| 200 | Collation: uom.Collation, |
| 201 | } |
| 202 | if uom.Upsert != nil { |
| 203 | um.Upsert = *uom.Upsert |
| 204 | um.UpsertSet = true |
| 205 | } |
| 206 | |
| 207 | converted := driver.UpdateOneModel{ |
| 208 | UpdateModel: um, |
| 209 | Filter: uom.Filter, |
| 210 | Update: uom.Update, |
| 211 | } |
| 212 | if uom.ArrayFilters != nil { |
| 213 | converted.ArrayFilters = *uom.ArrayFilters |
| 214 | converted.ArrayFiltersSet = true |
| 215 | } |
| 216 | |
| 217 | return converted |
| 218 | } |
| 219 | |
| 220 | // UpdateManyModel is the write model for updateMany operations. |
| 221 | type UpdateManyModel struct { |
| 222 | Collation *options.Collation |
| 223 | Upsert *bool |
| 224 | Filter interface{} |
| 225 | Update interface{} |
| 226 | ArrayFilters *options.ArrayFilters |
| 227 | } |
| 228 | |
| 229 | // NewUpdateManyModel creates a new UpdateManyModel. |
| 230 | func NewUpdateManyModel() *UpdateManyModel { |
| 231 | return &UpdateManyModel{} |
| 232 | } |
| 233 | |
| 234 | // SetFilter sets the filter for the UpdateManyModel. |
| 235 | func (umm *UpdateManyModel) SetFilter(filter interface{}) *UpdateManyModel { |
| 236 | umm.Filter = filter |
| 237 | return umm |
| 238 | } |
| 239 | |
| 240 | // SetUpdate sets the update document for the UpdateManyModel. |
| 241 | func (umm *UpdateManyModel) SetUpdate(update interface{}) *UpdateManyModel { |
| 242 | umm.Update = update |
| 243 | return umm |
| 244 | } |
| 245 | |
| 246 | // SetArrayFilters specifies a set of filters specifying to which array elements an update should apply. |
| 247 | func (umm *UpdateManyModel) SetArrayFilters(filters options.ArrayFilters) *UpdateManyModel { |
| 248 | umm.ArrayFilters = &filters |
| 249 | return umm |
| 250 | } |
| 251 | |
| 252 | // SetCollation sets the collation for the UpdateManyModel. |
| 253 | func (umm *UpdateManyModel) SetCollation(collation *options.Collation) *UpdateManyModel { |
| 254 | umm.Collation = collation |
| 255 | return umm |
| 256 | } |
| 257 | |
| 258 | // SetUpsert specifies if a new document should be created if no document matches the query. |
| 259 | func (umm *UpdateManyModel) SetUpsert(upsert bool) *UpdateManyModel { |
| 260 | umm.Upsert = &upsert |
| 261 | return umm |
| 262 | } |
| 263 | |
| 264 | func (umm *UpdateManyModel) convertModel() driver.WriteModel { |
| 265 | um := driver.UpdateModel{ |
| 266 | Collation: umm.Collation, |
| 267 | } |
| 268 | if umm.Upsert != nil { |
| 269 | um.Upsert = *umm.Upsert |
| 270 | um.UpsertSet = true |
| 271 | } |
| 272 | |
| 273 | converted := driver.UpdateManyModel{ |
| 274 | UpdateModel: um, |
| 275 | Filter: umm.Filter, |
| 276 | Update: umm.Update, |
| 277 | } |
| 278 | if umm.ArrayFilters != nil { |
| 279 | converted.ArrayFilters = *umm.ArrayFilters |
| 280 | converted.ArrayFiltersSet = true |
| 281 | } |
| 282 | |
| 283 | return converted |
| 284 | } |
| 285 | |
| 286 | func dispatchToMongoModel(model driver.WriteModel) WriteModel { |
| 287 | switch conv := model.(type) { |
| 288 | case driver.InsertOneModel: |
| 289 | return &InsertOneModel{ |
| 290 | Document: conv.Document, |
| 291 | } |
| 292 | case driver.DeleteOneModel: |
| 293 | return &DeleteOneModel{ |
| 294 | Filter: conv.Filter, |
| 295 | Collation: conv.Collation, |
| 296 | } |
| 297 | case driver.DeleteManyModel: |
| 298 | return &DeleteManyModel{ |
| 299 | Filter: conv.Filter, |
| 300 | Collation: conv.Collation, |
| 301 | } |
| 302 | case driver.ReplaceOneModel: |
| 303 | rom := &ReplaceOneModel{ |
| 304 | Filter: conv.Filter, |
| 305 | Replacement: conv.Replacement, |
| 306 | Collation: conv.Collation, |
| 307 | } |
| 308 | if conv.UpsertSet { |
| 309 | rom.Upsert = &conv.Upsert |
| 310 | } |
| 311 | return rom |
| 312 | case driver.UpdateOneModel: |
| 313 | uom := &UpdateOneModel{ |
| 314 | Filter: conv.Filter, |
| 315 | Update: conv.Update, |
| 316 | Collation: conv.Collation, |
| 317 | } |
| 318 | if conv.UpsertSet { |
| 319 | uom.Upsert = &conv.Upsert |
| 320 | } |
| 321 | if conv.ArrayFiltersSet { |
| 322 | uom.ArrayFilters = &conv.ArrayFilters |
| 323 | } |
| 324 | return uom |
| 325 | case driver.UpdateManyModel: |
| 326 | umm := &UpdateManyModel{ |
| 327 | Filter: conv.Filter, |
| 328 | Update: conv.Update, |
| 329 | Collation: conv.Collation, |
| 330 | } |
| 331 | if conv.UpsertSet { |
| 332 | umm.Upsert = &conv.Upsert |
| 333 | } |
| 334 | if conv.ArrayFiltersSet { |
| 335 | umm.ArrayFilters = &conv.ArrayFilters |
| 336 | } |
| 337 | return umm |
| 338 | } |
| 339 | |
| 340 | return nil |
| 341 | } |