mongo 2.0.6 → 2.1.0.beta

Sign up to get free protection for your applications and to get access to all the features.
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