mongo 2.0.6 → 2.1.0.beta

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (119) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/lib/mongo.rb +2 -0
  5. data/lib/mongo/bulk_write.rb +1 -0
  6. data/lib/mongo/bulk_write/bulk_writable.rb +87 -31
  7. data/lib/mongo/bulk_write/deletable.rb +8 -7
  8. data/lib/mongo/bulk_write/insertable.rb +4 -3
  9. data/lib/mongo/bulk_write/ordered_bulk_write.rb +6 -6
  10. data/lib/mongo/bulk_write/replacable.rb +4 -3
  11. data/lib/mongo/bulk_write/result.rb +138 -0
  12. data/lib/mongo/bulk_write/unordered_bulk_write.rb +5 -8
  13. data/lib/mongo/bulk_write/updatable.rb +8 -7
  14. data/lib/mongo/client.rb +36 -4
  15. data/lib/mongo/cluster.rb +39 -4
  16. data/lib/mongo/cluster/topology/replica_set.rb +20 -4
  17. data/lib/mongo/cluster/topology/sharded.rb +1 -1
  18. data/lib/mongo/collection.rb +282 -29
  19. data/lib/mongo/collection/view/aggregation.rb +32 -4
  20. data/lib/mongo/collection/view/iterable.rb +2 -1
  21. data/lib/mongo/collection/view/map_reduce.rb +3 -1
  22. data/lib/mongo/collection/view/readable.rb +89 -14
  23. data/lib/mongo/collection/view/writable.rb +11 -5
  24. data/lib/mongo/cursor.rb +11 -3
  25. data/lib/mongo/dbref.rb +113 -0
  26. data/lib/mongo/error.rb +6 -2
  27. data/lib/mongo/error/parser.rb +1 -1
  28. data/lib/mongo/event/description_changed.rb +1 -1
  29. data/lib/mongo/grid/file.rb +1 -1
  30. data/lib/mongo/grid/fs.rb +2 -5
  31. data/lib/mongo/monitoring.rb +199 -0
  32. data/lib/mongo/monitoring/command_log_subscriber.rb +88 -0
  33. data/lib/mongo/monitoring/event.rb +17 -0
  34. data/lib/mongo/monitoring/event/command_failed.rb +96 -0
  35. data/lib/mongo/monitoring/event/command_started.rb +88 -0
  36. data/lib/mongo/monitoring/event/command_succeeded.rb +96 -0
  37. data/lib/mongo/monitoring/publishable.rb +96 -0
  38. data/lib/mongo/operation.rb +1 -0
  39. data/lib/mongo/operation/executable.rb +1 -1
  40. data/lib/mongo/operation/parallel_scan.rb +76 -0
  41. data/lib/mongo/operation/parallel_scan/result.rb +72 -0
  42. data/lib/mongo/operation/specifiable.rb +18 -0
  43. data/lib/mongo/operation/write/bulk/bulk_delete.rb +1 -1
  44. data/lib/mongo/operation/write/bulk/bulk_insert.rb +1 -1
  45. data/lib/mongo/operation/write/bulk/bulk_mergable.rb +2 -2
  46. data/lib/mongo/operation/write/bulk/bulk_update.rb +1 -1
  47. data/lib/mongo/operation/write/bulk/bulk_update/result.rb +13 -1
  48. data/lib/mongo/protocol/delete.rb +8 -13
  49. data/lib/mongo/protocol/get_more.rb +13 -13
  50. data/lib/mongo/protocol/insert.rb +8 -13
  51. data/lib/mongo/protocol/kill_cursors.rb +7 -11
  52. data/lib/mongo/protocol/query.rb +58 -20
  53. data/lib/mongo/protocol/reply.rb +12 -0
  54. data/lib/mongo/protocol/update.rb +13 -14
  55. data/lib/mongo/server.rb +23 -2
  56. data/lib/mongo/server/connectable.rb +0 -22
  57. data/lib/mongo/server/connection.rb +29 -0
  58. data/lib/mongo/server/description.rb +23 -1
  59. data/lib/mongo/server/monitor.rb +17 -1
  60. data/lib/mongo/server/monitor/connection.rb +24 -0
  61. data/lib/mongo/socket/ssl.rb +28 -16
  62. data/lib/mongo/socket/tcp.rb +1 -1
  63. data/lib/mongo/socket/unix.rb +1 -1
  64. data/lib/mongo/uri.rb +12 -5
  65. data/lib/mongo/version.rb +1 -1
  66. data/spec/mongo/auth/cr_spec.rb +9 -1
  67. data/spec/mongo/auth/ldap_spec.rb +9 -1
  68. data/spec/mongo/auth/scram_spec.rb +9 -1
  69. data/spec/mongo/auth/x509_spec.rb +9 -1
  70. data/spec/mongo/{bulk/bulk_write_spec.rb → bulk_write_spec.rb} +15 -15
  71. data/spec/mongo/client_spec.rb +42 -0
  72. data/spec/mongo/cluster/topology/replica_set_spec.rb +16 -9
  73. data/spec/mongo/cluster/topology/sharded_spec.rb +11 -3
  74. data/spec/mongo/cluster/topology/single_spec.rb +12 -4
  75. data/spec/mongo/cluster_spec.rb +55 -10
  76. data/spec/mongo/collection/view/aggregation_spec.rb +123 -1
  77. data/spec/mongo/collection/view/explainable_spec.rb +1 -1
  78. data/spec/mongo/collection/view/map_reduce_spec.rb +1 -1
  79. data/spec/mongo/collection/view/readable_spec.rb +251 -6
  80. data/spec/mongo/collection/view/writable_spec.rb +4 -4
  81. data/spec/mongo/collection/view_spec.rb +233 -71
  82. data/spec/mongo/collection_spec.rb +905 -9
  83. data/spec/mongo/crud_spec.rb +2 -2
  84. data/spec/mongo/cursor_spec.rb +3 -3
  85. data/spec/mongo/dbref_spec.rb +149 -0
  86. data/spec/mongo/monitoring_spec.rb +168 -0
  87. data/spec/mongo/operation/map_reduce_spec.rb +1 -1
  88. data/spec/mongo/operation/write/bulk/bulk_delete_spec.rb +1 -1
  89. data/spec/mongo/operation/write/bulk/bulk_insert_spec.rb +2 -2
  90. data/spec/mongo/operation/write/bulk/bulk_update_spec.rb +1 -1
  91. data/spec/mongo/operation/write/delete_spec.rb +1 -1
  92. data/spec/mongo/operation/write/insert_spec.rb +2 -2
  93. data/spec/mongo/operation/write/update_spec.rb +1 -1
  94. data/spec/mongo/protocol/query_spec.rb +0 -29
  95. data/spec/mongo/server/connection_pool_spec.rb +18 -6
  96. data/spec/mongo/server/connection_spec.rb +12 -4
  97. data/spec/mongo/server/description_spec.rb +7 -3
  98. data/spec/mongo/server/monitor_spec.rb +30 -0
  99. data/spec/mongo/server_discovery_and_monitoring_spec.rb +11 -4
  100. data/spec/mongo/server_selection_spec.rb +14 -6
  101. data/spec/mongo/server_spec.rb +27 -8
  102. data/spec/mongo/socket/ssl_spec.rb +94 -8
  103. data/spec/mongo/uri_spec.rb +25 -9
  104. data/spec/spec_helper.rb +29 -20
  105. data/spec/support/authorization.rb +19 -4
  106. data/spec/support/certificates/client.pem +4 -4
  107. data/spec/support/crud/read.rb +9 -10
  108. data/spec/support/crud/write.rb +24 -20
  109. data/spec/support/sdam/rs/equal_electionids.yml +45 -0
  110. data/spec/support/sdam/rs/new_primary_new_electionid.yml +98 -0
  111. data/spec/support/sdam/rs/null_election_id.yml +144 -0
  112. data/spec/support/sdam/rs/primary_disconnect_electionid.yml +124 -0
  113. data/spec/support/sdam/sharded/mongos_disconnect.yml +104 -0
  114. data/spec/support/server_discovery_and_monitoring.rb +19 -2
  115. data/spec/support/shared/bulk_write.rb +26 -22
  116. data/spec/support/shared/server_selector.rb +2 -1
  117. metadata +31 -7
  118. metadata.gz.sig +0 -0
  119. data/lib/mongo/error/invalid_uri_option.rb +0 -38
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 391a49fc68da96ed3daf59dae9e7006edd6eb7c4
4
- data.tar.gz: c9b0c470d42785c446fa2c2ae21273bd45f487ea
3
+ metadata.gz: b6616ddb03b3417535c99796a74defa18bb90777
4
+ data.tar.gz: 300c32fe7122805036f67b387f0bb68648a8b759
5
5
  SHA512:
6
- metadata.gz: b77002840a210f7bf8c98114529edd2d0a8891dc6518fcd3c3d1337b2648cf2b31b9d3564aab8ab404521232713a452986cfd6202bdaa69c06fde024305befbe
7
- data.tar.gz: 146937702a43742e5e678845431b61b071c6b3573084dac4f7cb196f3ec601c97d78a248c39c1066a5fd7860f6195a72837210f6b8bdd84b7b6ed03328063f24
6
+ metadata.gz: 8046a19889e6f15481690eca65e8696834925bb7c1727a387af1d29e22fc63cb2d2640d5ddebf48e80d641e518dfc5a753d3a79713f655cccbbdba94215da1f3
7
+ data.tar.gz: 50f48316c5d9b17cb516467609667b5792472dbd0cbd43accc70c62a99ead9bdee595679f9d9b564db865606bbb55d7fc81176dd1669e0abd5c696803bd01132
Binary file
data.tar.gz.sig CHANGED
Binary file
@@ -15,6 +15,7 @@
15
15
  require 'forwardable'
16
16
  require 'bson'
17
17
  require 'openssl'
18
+ require 'mongo/monitoring'
18
19
  require 'mongo/loggable'
19
20
  require 'mongo/logger'
20
21
  require 'mongo/error'
@@ -27,6 +28,7 @@ require 'mongo/cluster'
27
28
  require 'mongo/collection'
28
29
  require 'mongo/cursor'
29
30
  require 'mongo/database'
31
+ require 'mongo/dbref'
30
32
  require 'mongo/grid'
31
33
  require 'mongo/index'
32
34
  require 'mongo/operation'
@@ -15,6 +15,7 @@
15
15
  require 'mongo/bulk_write/bulk_writable'
16
16
  require 'mongo/bulk_write/ordered_bulk_write'
17
17
  require 'mongo/bulk_write/unordered_bulk_write'
18
+ require 'mongo/bulk_write/result'
18
19
 
19
20
  module Mongo
20
21
  module BulkWrite
@@ -30,19 +30,60 @@ module Mongo
30
30
  include Replacable
31
31
  extend Forwardable
32
32
 
33
- # Delegate various methods to the collection.
34
- def_delegators :@collection, :database, :cluster, :next_primary
33
+ # Constant for number removed.
34
+ #
35
+ # @since 2.1.0
36
+ REMOVED_COUNT = 'n_removed'.freeze
37
+
38
+ # Constant for number inserted.
39
+ #
40
+ # @since 2.1.0
41
+ INSERTED_COUNT = 'n_inserted'.freeze
42
+
43
+ # Constant for inserted ids.
44
+ #
45
+ # @since 2.1.0
46
+ INSERTED_IDS = 'inserted_ids'.freeze
47
+
48
+ # Constant for number matched.
49
+ #
50
+ # @since 2.1.0
51
+ MATCHED_COUNT = 'n_matched'.freeze
52
+
53
+ # Constant for number modified.
54
+ #
55
+ # @since 2.1.0
56
+ MODIFIED_COUNT = 'n_modified'.freeze
57
+
58
+ # Constant for number upserted.
59
+ #
60
+ # @since 2.1.0
61
+ UPSERTED_COUNT = 'n_upserted'.freeze
62
+
63
+ # Constant for upserted ids.
64
+ #
65
+ # @since 2.1.0
66
+ UPSERTED_IDS = 'upserted_ids'.freeze
67
+
68
+ # Constant for indexes.
69
+ #
70
+ # @since 2.1.0
71
+ INDEXES = 'indexes'.freeze
35
72
 
36
73
  # The fields contained in the result document returned from executing the
37
74
  # operations.
38
75
  #
39
76
  # @since 2.0.0.
40
- RESULT_FIELDS = [ :n_inserted,
41
- :n_removed,
42
- :n_modified,
43
- :n_upserted,
44
- :n_matched ]
77
+ RESULT_FIELDS = [
78
+ INSERTED_COUNT,
79
+ REMOVED_COUNT,
80
+ MODIFIED_COUNT,
81
+ UPSERTED_COUNT,
82
+ MATCHED_COUNT
83
+ ].freeze
45
84
 
85
+ # Delegate various methods to the collection.
86
+ def_delegators :@collection, :database, :cluster, :next_primary
46
87
 
47
88
  # Initialize a bulk write object.
48
89
  #
@@ -76,9 +117,10 @@ module Mongo
76
117
  def execute
77
118
  server = next_primary
78
119
  validate_operations!
120
+ operation_id = Monitoring.next_operation_id
79
121
  merged_ops.each do |op|
80
122
  validate_type!(op.keys.first)
81
- execute_op(op, server)
123
+ execute_op(op, server, operation_id)
82
124
  end
83
125
  finalize
84
126
  end
@@ -86,13 +128,13 @@ module Mongo
86
128
  private
87
129
 
88
130
  def valid_doc?(doc)
89
- doc.respond_to?(:keys) ||
90
- doc.respond_to?(:document)
131
+ doc.respond_to?(:keys) || doc.respond_to?(:document)
91
132
  end
92
133
 
93
134
  def write_concern
94
- @write_concern ||= WriteConcern.get(@options[:write_concern]) ||
95
- @collection.write_concern
135
+ @write_concern ||= @options[:write_concern] ?
136
+ WriteConcern.get(@options[:write_concern]) :
137
+ @collection.write_concern
96
138
  end
97
139
 
98
140
  def validate_operations!
@@ -111,29 +153,30 @@ module Mongo
111
153
  type = op.keys.first
112
154
  ops = []
113
155
  while op[type].size > server.max_write_batch_size
114
- ops << { type => op[type].shift(server.max_write_batch_size),
115
- :indexes => op[:indexes].shift(server.max_write_batch_size) }
156
+ ops << {
157
+ type => op[type].shift(server.max_write_batch_size),
158
+ INDEXES => op[INDEXES].shift(server.max_write_batch_size)
159
+ }
116
160
  end
117
161
  ops << op
118
162
  end
119
163
 
120
164
  def split(op, type)
121
165
  n = op[type].size/2
122
- [ { type => op[type].shift(n),
123
- :indexes => op[:indexes].shift(n) },
124
- { type => op[type],
125
- :indexes => op[:indexes] }
166
+ [
167
+ { type => op[type].shift(n), INDEXES => op[INDEXES].shift(n) },
168
+ { type => op[type], INDEXES => op[INDEXES] }
126
169
  ]
127
170
  end
128
171
 
129
- def execute_op(operation, server)
172
+ def execute_op(operation, server, operation_id)
130
173
  ops = max_write_batches(operation, server)
131
174
 
132
175
  until ops.empty?
133
176
  op = ops.shift
134
177
  type = op.keys.first
135
178
  begin
136
- process(send(type, op, server), op[:indexes])
179
+ process(send(type, op, server, operation_id), op[INDEXES])
137
180
  rescue Error::MaxBSONSize, Error::MaxMessageSize => ex
138
181
  raise ex if op[type].size < 2
139
182
  ops = split(op, type) + ops
@@ -144,15 +187,16 @@ module Mongo
144
187
  def merge_consecutive_ops(ops)
145
188
  ops.each_with_index.inject([]) do |merged, (op, i)|
146
189
  type = op.keys.first
147
- op[:indexes] ||= [ i ]
190
+ op[INDEXES] ||= [ i ]
148
191
  previous = merged.last
149
192
  if previous && previous.keys.first == type
150
- merged[-1].merge!(type => previous[type] << op[type],
151
- :indexes => previous[:indexes] + op[:indexes])
193
+ merged[-1].merge!(
194
+ type => previous[type] << op[type],
195
+ INDEXES => previous[INDEXES] + op[INDEXES]
196
+ )
152
197
  merged
153
198
  else
154
- merged << { type => [ op[type] ].flatten,
155
- :indexes => op[:indexes] }
199
+ merged << { type => [ op[type] ].flatten, INDEXES => op[INDEXES] }
156
200
  end
157
201
  end
158
202
  end
@@ -166,7 +210,7 @@ module Mongo
166
210
  merged
167
211
  end
168
212
  ops_hash.keys.reduce([]) do |ops_list, type|
169
- ops_list << { type => ops_hash[type], :indexes => indexes[type] }
213
+ ops_list << { type => ops_hash[type], INDEXES => indexes[type] }
170
214
  end
171
215
  end
172
216
 
@@ -184,13 +228,25 @@ module Mongo
184
228
  ) if result.respond_to?(field)
185
229
  end
186
230
 
187
- results.merge!(
188
- write_errors: ((results[:write_errors] || []) << write_errors).flatten
189
- ) if write_errors
231
+ if result.respond_to?(INSERTED_IDS)
232
+ results.merge!(INSERTED_IDS => result.inserted_ids)
233
+ end
190
234
 
191
- results.merge!(write_concern_errors: @write_concern_errors) if @write_concern_errors
235
+ if result.respond_to?(Operation::Write::BulkUpdate::Result::UPSERTED)
236
+ results.merge!(UPSERTED_IDS => result.upserted.map{ |doc| doc['_id'] })
237
+ end
238
+
239
+ if write_errors
240
+ results.merge!(
241
+ Error::WRITE_ERRORS => ((results[Error::WRITE_ERRORS] || []) << write_errors).flatten
242
+ )
243
+ end
244
+
245
+ if @write_concern_errors
246
+ results.merge!(Error::WRITE_CONCERN_ERRORS => @write_concern_errors)
247
+ end
192
248
  end
193
249
  end
194
250
  end
195
251
  end
196
- end
252
+ end
@@ -34,23 +34,24 @@ module Mongo
34
34
  end
35
35
  end
36
36
 
37
- def delete(ops, type, server)
37
+ def delete(ops, type, server, operation_id)
38
38
  Operation::Write::BulkDelete.new(
39
39
  :deletes => deletes(ops, type),
40
40
  :db_name => database.name,
41
41
  :coll_name => @collection.name,
42
42
  :write_concern => write_concern,
43
- :ordered => ordered?
43
+ :ordered => ordered?,
44
+ :operation_id => operation_id
44
45
  ).execute(server.context)
45
46
  end
46
47
 
47
- def delete_one(op, server)
48
- delete(op[:delete_one], __method__, server)
48
+ def delete_one(op, server, operation_id)
49
+ delete(op[:delete_one], __method__, server, operation_id)
49
50
  end
50
51
 
51
- def delete_many(op, server)
52
- delete(op[:delete_many], __method__, server)
52
+ def delete_many(op, server, operation_id)
53
+ delete(op[:delete_many], __method__, server, operation_id)
53
54
  end
54
55
  end
55
56
  end
56
- end
57
+ end
@@ -33,16 +33,17 @@ module Mongo
33
33
  end
34
34
  end
35
35
 
36
- def insert_one(op, server)
36
+ def insert_one(op, server, operation_id)
37
37
  validate_insert_ops!(__method__, op[:insert_one])
38
38
  Operation::Write::BulkInsert.new(
39
39
  :documents => op[:insert_one].flatten,
40
40
  :db_name => database.name,
41
41
  :coll_name => @collection.name,
42
42
  :write_concern => write_concern,
43
- :ordered => ordered?
43
+ :ordered => ordered?,
44
+ :operation_id => operation_id
44
45
  ).execute(server.context)
45
46
  end
46
47
  end
47
48
  end
48
- end
49
+ end
@@ -13,11 +13,12 @@
13
13
  # limitations under the License.
14
14
 
15
15
  module Mongo
16
-
17
16
  module BulkWrite
18
17
 
18
+ # Encapsulates behaviour around an ordered bulk write operation.
19
+ #
20
+ # @since 2.0.0
19
21
  class OrderedBulkWrite
20
-
21
22
  include BulkWritable
22
23
 
23
24
  private
@@ -36,13 +37,12 @@ module Mongo
36
37
  end
37
38
 
38
39
  def stop?
39
- @results.keys.include?(:write_errors)
40
+ @results.keys.include?(Error::WRITE_ERRORS)
40
41
  end
41
42
 
42
43
  def finalize
43
- raise Error::BulkWriteError.new(@results) if @results[:write_concern_errors]
44
- @results
44
+ Result.new(@results).validate!
45
45
  end
46
46
  end
47
47
  end
48
- end
48
+ end
@@ -43,15 +43,16 @@ module Mongo
43
43
  end
44
44
  end
45
45
 
46
- def replace_one(op, server)
46
+ def replace_one(op, server, operation_id)
47
47
  Operation::Write::BulkUpdate.new(
48
48
  :updates => replace_ops(op[:replace_one], __method__),
49
49
  :db_name => database.name,
50
50
  :coll_name => @collection.name,
51
51
  :write_concern => write_concern,
52
- :ordered => ordered?
52
+ :ordered => ordered?,
53
+ :operation_id => operation_id
53
54
  ).execute(server.context)
54
55
  end
55
56
  end
56
57
  end
57
- end
58
+ end
@@ -0,0 +1,138 @@
1
+ # Copyright (C) 2015 MongoDB, Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ module Mongo
16
+ module BulkWrite
17
+
18
+ # Wraps a series of bulk write operations in a result object.
19
+ #
20
+ # @since 2.0.6
21
+ class Result
22
+
23
+ # Returns the number of documents deleted.
24
+ #
25
+ # @example Get the number of deleted documents.
26
+ # result.deleted_count
27
+ #
28
+ # @return [ Integer ] The number deleted.
29
+ #
30
+ # @since 2.1.0
31
+ def deleted_count
32
+ @results[BulkWritable::REMOVED_COUNT]
33
+ end
34
+
35
+ # Create the new result object from the results document.
36
+ #
37
+ # @example Create the new result.
38
+ # Result.new({ 'n_inserted' => 10 })
39
+ #
40
+ # @param [ BSON::Document, Hash ] results The results document.
41
+ #
42
+ # @since 2.1.0
43
+ def initialize(results)
44
+ @results = results
45
+ end
46
+
47
+ # Returns the number of documents inserted.
48
+ #
49
+ # @example Get the number of inserted documents.
50
+ # result.inserted_count
51
+ #
52
+ # @return [ Integer ] The number inserted.
53
+ #
54
+ # @since 2.1.0
55
+ def inserted_count
56
+ @results[BulkWritable::INSERTED_COUNT]
57
+ end
58
+
59
+ # Get the inserted document ids, if the operation has inserts.
60
+ #
61
+ # @example Get the inserted ids.
62
+ # result.inserted_ids
63
+ #
64
+ # @return [ Array<BSON::ObjectId> ] The inserted ids.
65
+ #
66
+ # @since 2.1.0
67
+ def inserted_ids
68
+ @results[BulkWritable::INSERTED_IDS]
69
+ end
70
+
71
+ # Returns the number of documents matched.
72
+ #
73
+ # @example Get the number of matched documents.
74
+ # result.matched_count
75
+ #
76
+ # @return [ Integer ] The number matched.
77
+ #
78
+ # @since 2.1.0
79
+ def matched_count
80
+ @results[BulkWritable::MATCHED_COUNT]
81
+ end
82
+
83
+ # Returns the number of documents modified.
84
+ #
85
+ # @example Get the number of modified documents.
86
+ # result.modified_count
87
+ #
88
+ # @return [ Integer ] The number modified.
89
+ #
90
+ # @since 2.1.0
91
+ def modified_count
92
+ @results[BulkWritable::MODIFIED_COUNT]
93
+ end
94
+
95
+ # Returns the number of documents upserted.
96
+ #
97
+ # @example Get the number of upserted documents.
98
+ # result.upserted_count
99
+ #
100
+ # @return [ Integer ] The number upserted.
101
+ #
102
+ # @since 2.1.0
103
+ def upserted_count
104
+ @results[BulkWritable::UPSERTED_COUNT]
105
+ end
106
+
107
+ # Get the upserted document ids, if the operation has inserts.
108
+ #
109
+ # @example Get the upserted ids.
110
+ # result.upserted_ids
111
+ #
112
+ # @return [ Array<BSON::ObjectId> ] The upserted ids.
113
+ #
114
+ # @since 2.1.0
115
+ def upserted_ids
116
+ @results[BulkWritable::UPSERTED_IDS]
117
+ end
118
+
119
+ # Validates the bulk write result.
120
+ #
121
+ # @example Validate the result.
122
+ # result.validate!
123
+ #
124
+ # @raise [ Error::BulkWriteError ] If the result contains errors.
125
+ #
126
+ # @return [ Result ] The result.
127
+ #
128
+ # @since 2.1.0
129
+ def validate!
130
+ if @results[Error::WRITE_ERRORS] || @results[Error::WRITE_CONCERN_ERRORS]
131
+ raise Error::BulkWriteError.new(@results)
132
+ else
133
+ self
134
+ end
135
+ end
136
+ end
137
+ end
138
+ end