mongo 2.0.0.beta → 2.0.0.rc

Sign up to get free protection for your applications and to get access to all the features.
Files changed (136) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/Rakefile +14 -1
  5. data/lib/mongo.rb +2 -1
  6. data/lib/mongo/auth.rb +2 -2
  7. data/lib/mongo/bulk_write.rb +52 -0
  8. data/lib/mongo/bulk_write/bulk_writable.rb +191 -0
  9. data/lib/mongo/bulk_write/deletable.rb +60 -0
  10. data/lib/mongo/bulk_write/insertable.rb +52 -0
  11. data/lib/mongo/bulk_write/ordered_bulk_write.rb +48 -0
  12. data/lib/mongo/bulk_write/replacable.rb +57 -0
  13. data/lib/mongo/bulk_write/unordered_bulk_write.rb +46 -0
  14. data/lib/mongo/bulk_write/updatable.rb +68 -0
  15. data/lib/mongo/client.rb +15 -2
  16. data/lib/mongo/cluster/topology/replica_set.rb +1 -1
  17. data/lib/mongo/cluster/topology/sharded.rb +1 -1
  18. data/lib/mongo/cluster/topology/standalone.rb +1 -1
  19. data/lib/mongo/cluster/topology/unknown.rb +1 -1
  20. data/lib/mongo/collection.rb +1 -1
  21. data/lib/mongo/collection/view/aggregation.rb +1 -1
  22. data/lib/mongo/collection/view/readable.rb +1 -1
  23. data/lib/mongo/collection/view/writable.rb +5 -5
  24. data/lib/mongo/cursor.rb +0 -2
  25. data/lib/mongo/error.rb +4 -3
  26. data/lib/mongo/error/{bulk_write_failure.rb → bulk_write_error.rb} +2 -2
  27. data/lib/mongo/error/invalid_bulk_operation.rb +2 -2
  28. data/lib/mongo/error/invalid_bulk_operation_type.rb +36 -0
  29. data/lib/mongo/error/{empty_batch.rb → multi_index_drop.rb} +5 -10
  30. data/lib/mongo/grid/file/metadata.rb +1 -8
  31. data/lib/mongo/grid/fs.rb +5 -5
  32. data/lib/mongo/index/view.rb +90 -34
  33. data/lib/mongo/operation.rb +0 -1
  34. data/lib/mongo/operation/aggregate.rb +2 -2
  35. data/lib/mongo/operation/aggregate/result.rb +4 -0
  36. data/lib/mongo/operation/bulk_delete/result.rb +2 -127
  37. data/lib/mongo/operation/bulk_insert/result.rb +2 -132
  38. data/lib/mongo/operation/bulk_update/result.rb +2 -142
  39. data/lib/mongo/operation/command.rb +1 -1
  40. data/lib/mongo/operation/executable.rb +3 -3
  41. data/lib/mongo/operation/list_collections/result.rb +0 -2
  42. data/lib/mongo/operation/map_reduce.rb +1 -1
  43. data/lib/mongo/operation/read/collections_info.rb +1 -1
  44. data/lib/mongo/operation/read/get_more.rb +1 -1
  45. data/lib/mongo/operation/read/indexes.rb +1 -1
  46. data/lib/mongo/operation/read/list_collections.rb +1 -1
  47. data/lib/mongo/operation/read/list_indexes.rb +1 -1
  48. data/lib/mongo/operation/read/query.rb +1 -1
  49. data/lib/mongo/operation/specifiable.rb +18 -1
  50. data/lib/mongo/operation/write.rb +2 -0
  51. data/lib/mongo/operation/write/bulk_delete.rb +5 -19
  52. data/lib/mongo/operation/write/bulk_insert.rb +9 -40
  53. data/lib/mongo/operation/write/bulk_mergable.rb +67 -0
  54. data/lib/mongo/operation/write/bulk_update.rb +5 -19
  55. data/lib/mongo/operation/write/command.rb +1 -1
  56. data/lib/mongo/operation/write/command/{ensure_index.rb → create_index.rb} +4 -9
  57. data/lib/mongo/operation/write/command/delete.rb +4 -4
  58. data/lib/mongo/operation/write/command/drop_index.rb +1 -1
  59. data/lib/mongo/operation/write/command/insert.rb +4 -4
  60. data/lib/mongo/operation/write/command/update.rb +4 -4
  61. data/lib/mongo/operation/write/create_index.rb +12 -7
  62. data/lib/mongo/operation/write/create_user.rb +1 -1
  63. data/lib/mongo/operation/write/delete.rb +1 -1
  64. data/lib/mongo/operation/write/drop_index.rb +1 -1
  65. data/lib/mongo/operation/write/insert.rb +1 -1
  66. data/lib/mongo/operation/write/legacy_bulk_mergable.rb +83 -0
  67. data/lib/mongo/operation/write/remove_user.rb +1 -1
  68. data/lib/mongo/operation/write/update.rb +1 -1
  69. data/lib/mongo/{bulk.rb → options.rb} +2 -2
  70. data/lib/mongo/options/mapper.rb +78 -0
  71. data/lib/mongo/server.rb +2 -2
  72. data/lib/mongo/server/connection_pool/queue.rb +1 -1
  73. data/lib/mongo/server/description.rb +1 -1
  74. data/lib/mongo/server/description/inspector.rb +1 -1
  75. data/lib/mongo/server_selector.rb +1 -1
  76. data/lib/mongo/socket/unix.rb +2 -4
  77. data/lib/mongo/version.rb +1 -1
  78. data/lib/mongo/write_concern/acknowledged.rb +15 -1
  79. data/lib/mongo/write_concern/normalizable.rb +0 -22
  80. data/lib/mongo/write_concern/unacknowledged.rb +12 -0
  81. data/spec/mongo/bulk/bulk_write_spec.rb +178 -91
  82. data/spec/mongo/collection/view/aggregation_spec.rb +14 -1
  83. data/spec/mongo/collection/view/explainable_spec.rb +1 -1
  84. data/spec/mongo/collection/view/map_reduce_spec.rb +2 -2
  85. data/spec/mongo/collection/view/readable_spec.rb +2 -2
  86. data/spec/mongo/collection/view/writable_spec.rb +7 -7
  87. data/spec/mongo/collection/view_spec.rb +14 -5
  88. data/spec/mongo/collection_spec.rb +5 -5
  89. data/spec/mongo/cursor_spec.rb +3 -3
  90. data/spec/mongo/database_spec.rb +4 -8
  91. data/spec/mongo/grid/fs_spec.rb +8 -8
  92. data/spec/mongo/index/view_spec.rb +139 -35
  93. data/spec/mongo/operation/aggregate_spec.rb +14 -22
  94. data/spec/mongo/operation/command_spec.rb +8 -16
  95. data/spec/mongo/operation/map_reduce_spec.rb +1 -1
  96. data/spec/mongo/operation/read/indexes_spec.rb +2 -2
  97. data/spec/mongo/operation/write/bulk_delete_spec.rb +1 -239
  98. data/spec/mongo/operation/write/bulk_insert_spec.rb +3 -234
  99. data/spec/mongo/operation/write/bulk_update_spec.rb +1 -289
  100. data/spec/mongo/operation/write/command/delete_spec.rb +0 -13
  101. data/spec/mongo/operation/write/command/insert_spec.rb +0 -14
  102. data/spec/mongo/operation/write/command/update_spec.rb +0 -14
  103. data/spec/mongo/operation/write/{ensure_index_spec.rb → create_index_spec.rb} +8 -26
  104. data/spec/mongo/operation/write/delete_spec.rb +1 -1
  105. data/spec/mongo/operation/write/drop_index_spec.rb +1 -1
  106. data/spec/mongo/operation/write/insert_spec.rb +3 -3
  107. data/spec/mongo/operation/write/update_spec.rb +1 -1
  108. data/spec/mongo/server_selection_spec.rb +2 -2
  109. data/spec/support/authorization.rb +4 -2
  110. data/spec/support/server_selection.rb +25 -8
  111. data/spec/support/server_selection/selection/ReplicaSetNoPrimary/read/Nearest.yml +4 -10
  112. data/spec/support/server_selection/selection/ReplicaSetNoPrimary/read/Nearest_non_matching.yml +6 -12
  113. data/spec/support/server_selection/selection/ReplicaSetNoPrimary/read/Primary.yml +4 -6
  114. data/spec/support/server_selection/selection/ReplicaSetNoPrimary/read/PrimaryPreferred.yml +4 -10
  115. data/spec/support/server_selection/selection/ReplicaSetNoPrimary/read/PrimaryPreferred_non_matching.yml +6 -12
  116. data/spec/support/server_selection/selection/ReplicaSetNoPrimary/read/Secondary.yml +4 -10
  117. data/spec/support/server_selection/selection/ReplicaSetNoPrimary/read/SecondaryPreferred.yml +4 -10
  118. data/spec/support/server_selection/selection/ReplicaSetNoPrimary/read/SecondaryPreferred_non_matching.yml +6 -12
  119. data/spec/support/server_selection/selection/ReplicaSetNoPrimary/read/Secondary_non_matching.yml +6 -12
  120. data/spec/support/server_selection/selection/ReplicaSetWithPrimary/read/Nearest.yml +9 -17
  121. data/spec/support/server_selection/selection/ReplicaSetWithPrimary/read/Nearest_non_matching.yml +9 -17
  122. data/spec/support/server_selection/selection/ReplicaSetWithPrimary/read/Primary.yml +6 -10
  123. data/spec/support/server_selection/selection/ReplicaSetWithPrimary/read/PrimaryPreferred.yml +11 -21
  124. data/spec/support/server_selection/selection/ReplicaSetWithPrimary/read/PrimaryPreferred_non_matching.yml +11 -18
  125. data/spec/support/server_selection/selection/ReplicaSetWithPrimary/read/Secondary.yml +31 -0
  126. data/spec/support/server_selection/selection/ReplicaSetWithPrimary/read/SecondaryPreferred.yml +31 -0
  127. data/spec/support/server_selection/selection/ReplicaSetWithPrimary/read/SecondaryPreferred_non_matching.yml +29 -0
  128. data/spec/support/server_selection/selection/ReplicaSetWithPrimary/read/Secondary_non_matching.yml +26 -0
  129. data/spec/support/server_selection/selection/Sharded/read/SecondaryPreferred.yml +4 -10
  130. data/spec/support/server_selection/selection/Single/read/SecondaryPreferred.yml +2 -6
  131. data/spec/support/server_selection/selection/Unknown/read/SecondaryPreferred.yml +0 -2
  132. data/spec/support/shared/bulk_write.rb +109 -72
  133. metadata +29 -10
  134. metadata.gz.sig +0 -0
  135. data/lib/mongo/bulk/bulk_write.rb +0 -307
  136. data/lib/mongo/operation/batchable.rb +0 -103
@@ -129,7 +129,7 @@ module Mongo
129
129
  #
130
130
  # @since 2.0.0
131
131
  def initialize(document)
132
- @document = default_document.merge(normalize(document))
132
+ @document = default_document.merge(Options::Mapper.transform(document, MAPPINGS))
133
133
  @client_md5 = Digest::MD5.new
134
134
  end
135
135
 
@@ -202,13 +202,6 @@ module Mongo
202
202
 
203
203
  private
204
204
 
205
- def normalize(document)
206
- document.reduce(BSON::Document.new) do |doc, (key, value)|
207
- doc[MAPPINGS[key] || key] = value
208
- doc
209
- end
210
- end
211
-
212
205
  def default_document
213
206
  BSON::Document.new(
214
207
  :_id => BSON::ObjectId.new,
@@ -100,7 +100,7 @@ module Mongo
100
100
  @options = options
101
101
  @chunks_collection = database[chunks_name]
102
102
  @files_collection = database[files_name]
103
- chunks_collection.indexes.create(INDEX_SPEC, :unique => true)
103
+ chunks_collection.indexes.create_one(INDEX_SPEC, :unique => true)
104
104
  end
105
105
 
106
106
  # Get the prefix for the GridFS
@@ -118,16 +118,16 @@ module Mongo
118
118
  # Remove a single file from the GridFS.
119
119
  #
120
120
  # @example Remove a file from the GridFS.
121
- # fs.remove_one(file)
121
+ # fs.delete_one(file)
122
122
  #
123
123
  # @param [ Grid::File ] file The file to remove.
124
124
  #
125
125
  # @return [ Result ] The result of the remove.
126
126
  #
127
127
  # @since 2.0.0
128
- def remove_one(file)
129
- files_collection.find(:_id => file.id).remove_one
130
- chunks_collection.find(:files_id => file.id).remove_many
128
+ def delete_one(file)
129
+ files_collection.find(:_id => file.id).delete_one
130
+ chunks_collection.find(:files_id => file.id).delete_many
131
131
  end
132
132
 
133
133
  private
@@ -42,25 +42,42 @@ module Mongo
42
42
  # @since 2.0.0
43
43
  NAME = 'name'.freeze
44
44
 
45
- # Drop an index by its specification.
45
+ # The mappings of Ruby index options to server options.
46
46
  #
47
- # @example Drop the index by spec.
48
- # view.drop(name: 1)
47
+ # @since 2.0.0
48
+ OPTIONS = {
49
+ :background => :background,
50
+ :bits => :bits,
51
+ :bucket_size => :bucketSize,
52
+ :default_language => :default_language,
53
+ :expire_after => :expireAfterSeconds,
54
+ :key => :key,
55
+ :language_override => :language_override,
56
+ :max => :max,
57
+ :min => :min,
58
+ :name => :name,
59
+ :sparse => :sparse,
60
+ :sphere_version => :'2dsphereIndexVersion',
61
+ :storage_engine => :storageEngine,
62
+ :text_version => :textIndexVersion,
63
+ :unique => :unique,
64
+ :version => :v,
65
+ :weights => :weights
66
+ }.freeze
67
+
68
+ # Drop an index by its name.
49
69
  #
50
70
  # @example Drop an index by its name.
51
- # view.drop('name_1')
71
+ # view.drop_one('name_1')
52
72
  #
53
- # @param [ Hash, String ] spec The index spec or name to drop.
73
+ # @param [ String ] name The name of the index.
54
74
  #
55
75
  # @return [ Result ] The response.
56
76
  #
57
77
  # @since 2.0.0
58
- def drop(spec)
59
- Operation::Write::DropIndex.new(
60
- db_name: database.name,
61
- coll_name: collection.name,
62
- index_name: spec.is_a?(String) ? spec : index_name(spec)
63
- ).execute(next_primary.context)
78
+ def drop_one(name)
79
+ raise Error::MultiIndexDrop.new if name == '*'
80
+ drop_by_name(name)
64
81
  end
65
82
 
66
83
  # Drop all indexes on the collection.
@@ -72,12 +89,15 @@ module Mongo
72
89
  #
73
90
  # @since 2.0.0
74
91
  def drop_all
75
- drop('*')
92
+ drop_by_name('*')
76
93
  end
77
94
 
78
- # Creates an index on the collection.
95
+ # Creates an index on the collection.
96
+ #
97
+ # @example Create a unique index on the collection.
98
+ # view.create_one({ name: 1 }, { unique: true })
79
99
  #
80
- # @param [ Hash ] spec A hash of field name/direction pairs.
100
+ # @param [ Hash ] keys A hash of field name/direction pairs.
81
101
  # @param [ Hash ] options Options for this index.
82
102
  #
83
103
  # @option options [ true, false ] :unique (false) If true, this index will enforce
@@ -101,13 +121,32 @@ module Mongo
101
121
  # @return [ Result ] The response.
102
122
  #
103
123
  # @since 2.0.0
104
- def create(spec, options = {})
105
- Operation::Write::EnsureIndex.new(
106
- index: spec,
124
+ def create_one(keys, options = {})
125
+ create_many({ key: keys }.merge(options))
126
+ end
127
+
128
+ # Creates multiple indexes on the collection.
129
+ #
130
+ # @example Create multiple indexes.
131
+ # view.create_many([
132
+ # { key: { name: 1 }, unique: true },
133
+ # { key: { age: -1 }, background: true }
134
+ # ])
135
+ #
136
+ # @note On MongoDB 3.0.0 and higher, the indexes will be created in
137
+ # parallel on the server.
138
+ #
139
+ # @param [ Array<Hash> ] models The index specifications. Each model MUST
140
+ # include a :key option.
141
+ #
142
+ # @return [ Result ] The result of the command.
143
+ #
144
+ # @since 2.0.0
145
+ def create_many(*models)
146
+ Operation::Write::CreateIndex.new(
147
+ indexes: normalize_models(models.flatten),
107
148
  db_name: database.name,
108
149
  coll_name: collection.name,
109
- index_name: options[:name] || index_name(spec),
110
- options: options
111
150
  ).execute(next_primary.context)
112
151
  end
113
152
 
@@ -117,17 +156,17 @@ module Mongo
117
156
  # @example Get index information by name.
118
157
  # view.get('name_1')
119
158
  #
120
- # @example Get index information by spec.
159
+ # @example Get index information by the keys.
121
160
  # view.get(name: 1)
122
161
  #
123
- # @param [ Hash, String ] spec The index name or spec.
162
+ # @param [ Hash, String ] keys_or_name The index name or spec.
124
163
  #
125
164
  # @return [ Hash ] The index information.
126
165
  #
127
166
  # @since 2.0.0
128
- def get(spec)
167
+ def get(keys_or_name)
129
168
  find do |index|
130
- (index[NAME] == spec) || (index[KEY] == normalize_keys(spec))
169
+ (index[NAME] == keys_or_name) || (index[KEY] == normalize_keys(keys_or_name))
131
170
  end
132
171
  end
133
172
 
@@ -169,8 +208,16 @@ module Mongo
169
208
 
170
209
  private
171
210
 
172
- def limit
173
- -1
211
+ def drop_by_name(name)
212
+ Operation::Write::DropIndex.new(
213
+ db_name: database.name,
214
+ coll_name: collection.name,
215
+ index_name: name
216
+ ).execute(next_primary.context)
217
+ end
218
+
219
+ def index_name(spec)
220
+ spec.to_a.join('_')
174
221
  end
175
222
 
176
223
  def indexes_spec
@@ -185,19 +232,28 @@ module Mongo
185
232
  Operation::Read::Indexes.new(indexes_spec)
186
233
  end
187
234
 
188
- def send_initial_query(server)
189
- initial_query_op.execute(server.context)
235
+ def limit; -1; end
236
+
237
+ def normalize_keys(spec)
238
+ return false if spec.is_a?(String)
239
+ Options::Mapper.transform_keys_to_strings(spec)
190
240
  end
191
241
 
192
- def index_name(spec)
193
- spec.to_a.join('_')
242
+ def normalize_models(models)
243
+ with_generated_names(models).map do |model|
244
+ Options::Mapper.transform(model, OPTIONS)
245
+ end
194
246
  end
195
247
 
196
- def normalize_keys(spec)
197
- return false if spec.is_a?(String)
198
- spec.reduce({}) do |normalized, (key, value)|
199
- normalized[key.to_s] = value
200
- normalized
248
+ def send_initial_query(server)
249
+ initial_query_op.execute(server.context)
250
+ end
251
+
252
+ def with_generated_names(models)
253
+ models.dup.each do |model|
254
+ unless model[:name]
255
+ model[:name] = index_name(model[:key])
256
+ end
201
257
  end
202
258
  end
203
259
  end
@@ -17,7 +17,6 @@ require 'mongo/operation/executable'
17
17
  require 'mongo/operation/specifiable'
18
18
  require 'mongo/operation/limited'
19
19
  require 'mongo/operation/read_preferrable'
20
- require 'mongo/operation/batchable'
21
20
  require 'mongo/operation/read'
22
21
  require 'mongo/operation/write'
23
22
  require 'mongo/operation/aggregate'
@@ -56,7 +56,7 @@ module Mongo
56
56
  # server is not primary, the operation will be rerouted to the primary
57
57
  # with a warning.
58
58
  #
59
- # @params [ Mongo::Server::Context ] The context for this operation.
59
+ # @param [ Server::Context ] context The context for this operation.
60
60
  #
61
61
  # @return [ Result ] The operation response, if there is one.
62
62
  #
@@ -72,7 +72,7 @@ module Mongo
72
72
 
73
73
  def execute_message(context)
74
74
  context.with_connection do |connection|
75
- Result.new(connection.dispatch([ message(context) ]))
75
+ Result.new(connection.dispatch([ message(context) ])).validate!
76
76
  end
77
77
  end
78
78
 
@@ -78,6 +78,10 @@ module Mongo
78
78
  def cursor_document
79
79
  @cursor_document ||= reply.documents[0][CURSOR]
80
80
  end
81
+
82
+ def first_document
83
+ @first_document ||= reply.documents[0]
84
+ end
81
85
  end
82
86
  end
83
87
  end
@@ -21,8 +21,7 @@ module Mongo
21
21
  #
22
22
  # @since 2.0.0
23
23
  class Result < Operation::Result
24
-
25
- attr_reader :indexes
24
+ include BulkMergable
26
25
 
27
26
  # The aggregate number of deleted docs reported in the replies.
28
27
  #
@@ -43,60 +42,6 @@ module Mongo
43
42
  n += reply.documents.first[N]
44
43
  end
45
44
  end
46
-
47
- # Set a list of indexes of the operations creating this result.
48
- #
49
- # @example Set the list of indexes.
50
- # result.set_indexes([1,2,3])
51
- #
52
- # @return [ self ] The result.
53
- #
54
- # @since 2.0.0
55
- def set_indexes(indexes)
56
- @indexes = indexes
57
- self
58
- end
59
-
60
- # Aggregate the write errors returned from this result.
61
- #
62
- # @example Aggregate the write errors.
63
- # result.aggregate_write_errors
64
- #
65
- # @return [ Array ] The aggregate write errors.
66
- #
67
- # @since 2.0.0
68
- def aggregate_write_errors
69
- @replies.reduce(nil) do |errors, reply|
70
- if write_errors = reply.documents.first['writeErrors']
71
- errors ||= []
72
- write_errors.each do |write_error|
73
- errors << write_error.merge('index' => indexes[write_error['index']])
74
- end
75
- end
76
- errors
77
- end
78
- end
79
-
80
- # Aggregate the write concern errors returned from this result.
81
- #
82
- # @example Aggregate the write concern errors.
83
- # result.aggregate_write_concern_errors
84
- #
85
- # @return [ Array ] The aggregate write concern errors.
86
- #
87
- # @since 2.0.0
88
- def aggregate_write_concern_errors
89
- @replies.reduce(nil) do |errors, reply|
90
- if write_concern_errors = reply.documents.first['writeConcernErrors']
91
- errors ||= []
92
- write_concern_errors.each do |write_concern_error|
93
- errors << write_concern_error.merge('index' =>
94
- indexes[write_concern_error['index']])
95
- end
96
- end
97
- errors
98
- end
99
- end
100
45
  end
101
46
 
102
47
  # Defines custom behaviour of results when deleting.
@@ -104,8 +49,7 @@ module Mongo
104
49
  #
105
50
  # @since 2.0.0
106
51
  class LegacyResult < Operation::Result
107
-
108
- attr_reader :indexes
52
+ include LegacyBulkMergable
109
53
 
110
54
  # Gets the number of documents deleted.
111
55
  #
@@ -121,75 +65,6 @@ module Mongo
121
65
  n += reply.documents.first[N]
122
66
  end
123
67
  end
124
-
125
- # Set a list of indexes of the operations creating this result.
126
- #
127
- # @example Set the list of indexes.
128
- # result.set_indexes([1,2,3])
129
- #
130
- # @return [ self ] The result.
131
- #
132
- # @since 2.0.0
133
- def set_indexes(indexes)
134
- @indexes = indexes
135
- self
136
- end
137
-
138
- # Aggregate the write errors returned from this result.
139
- #
140
- # @example Aggregate the write errors.
141
- # result.aggregate_write_errors
142
- #
143
- # @return [ Array ] The aggregate write errors.
144
- #
145
- # @since 2.0.0
146
- def aggregate_write_errors
147
- @replies.each_with_index.reduce(nil) do |errors, (reply, i)|
148
- if reply_write_errors?(reply)
149
- errors ||= []
150
- errors << { 'errmsg' => reply.documents.first[Error::ERROR],
151
- 'index' => indexes[i],
152
- 'code' => reply.documents.first[Error::CODE] }
153
- end
154
- errors
155
- end
156
- end
157
-
158
- # Aggregate the write concern errors returned from this result.
159
- #
160
- # @example Aggregate the write concern errors.
161
- # result.aggregate_write_concern_errors
162
- #
163
- # @return [ Array ] The aggregate write concern errors.
164
- #
165
- # @since 2.0.0
166
- def aggregate_write_concern_errors
167
- @replies.each_with_index.reduce(nil) do |errors, (reply, i)|
168
- # @todo: only raise if error is timeout
169
- if error = reply_write_errors?(reply)
170
- errors ||= []
171
- note = reply.documents.first['wnote'] || reply.documents.first['jnote']
172
- if note
173
- code = reply.documents.first['code'] || Error::BAD_VALUE
174
- error_string = "#{code}: #{note}"
175
- else
176
- code = reply.documents.first['code'] || Error::UNKNOWN_ERROR
177
- error_string = "#{code}: #{error}"
178
- end
179
- errors << { 'errmsg' => error_string,
180
- 'index' => indexes[i],
181
- 'code' => code }
182
- end
183
- errors
184
- end
185
- end
186
-
187
- private
188
-
189
- def reply_write_errors?(reply)
190
- reply.documents.first[Error::ERROR] ||
191
- reply.documents.first[Error::ERRMSG]
192
- end
193
68
  end
194
69
  end
195
70
  end
@@ -21,8 +21,7 @@ module Mongo
21
21
  #
22
22
  # @since 2.0.0
23
23
  class Result < Operation::Result
24
-
25
- attr_reader :indexes
24
+ include BulkMergable
26
25
 
27
26
  # Gets the number of documents inserted.
28
27
  #
@@ -35,65 +34,6 @@ module Mongo
35
34
  def n_inserted
36
35
  written_count
37
36
  end
38
-
39
- # Set a list of indexes of the operations creating this result.
40
- #
41
- # @example Set the list of indexes.
42
- # result.set_indexes([1,2,3])
43
- #
44
- # @return [ self ] The result.
45
- #
46
- # @since 2.0.0
47
- def set_indexes(indexes)
48
- @indexes = indexes
49
- self
50
- end
51
-
52
- # Aggregate the write errors returned from this result.
53
- #
54
- # @example Aggregate the write errors.
55
- # result.aggregate_write_errors
56
- #
57
- # @return [ Array ] The aggregate write errors.
58
- #
59
- # @since 2.0.0
60
- def aggregate_write_errors
61
- @replies.reduce(nil) do |errors, reply|
62
- if write_errors = reply.documents.first['writeErrors']
63
- errors ||= []
64
- write_errors.each do |write_error|
65
- errors << write_error.merge('index' => indexes[write_error['index']])
66
- end
67
- end
68
- errors
69
- end
70
- end
71
-
72
- # Aggregate the write concern errors returned from this result.
73
- #
74
- # @example Aggregate the write concern errors.
75
- # result.aggregate_write_concern_errors
76
- #
77
- # @return [ Array ] The aggregate write concern errors.
78
- #
79
- # @since 2.0.0
80
- def aggregate_write_concern_errors
81
- @replies.each_with_index.reduce(nil) do |errors, (reply, i)|
82
- if write_concern_errors = reply.documents.first['writeConcernError']
83
- errors ||= []
84
- write_concern_errors.each do |write_concern_error|
85
- errors << write_concern_error.merge('index' =>
86
- indexes[write_concern_error['index']])
87
- end
88
- elsif reply.documents.first['errmsg']
89
- errors ||= []
90
- errors << { 'errmsg' => reply.documents.first['errmsg'],
91
- 'index' => indexes[i],
92
- 'code' => reply.documents.first['code'] }
93
- end
94
- errors
95
- end
96
- end
97
37
  end
98
38
 
99
39
  # Defines custom behaviour of results when inserting.
@@ -101,8 +41,7 @@ module Mongo
101
41
  #
102
42
  # @since 2.0.0
103
43
  class LegacyResult < Operation::Result
104
-
105
- attr_reader :indexes
44
+ include LegacyBulkMergable
106
45
 
107
46
  # Gets the number of documents inserted.
108
47
  #
@@ -119,75 +58,6 @@ module Mongo
119
58
  n
120
59
  end
121
60
  end
122
-
123
- # Set a list of indexes of the operations creating this result.
124
- #
125
- # @example Set the list of indexes.
126
- # result.set_indexes([1,2,3])
127
- #
128
- # @return [ self ] The result.
129
- #
130
- # @since 2.0.0
131
- def set_indexes(indexes)
132
- @indexes = indexes
133
- self
134
- end
135
-
136
- # Aggregate the write errors returned from this result.
137
- #
138
- # @example Aggregate the write errors.
139
- # result.aggregate_write_errors
140
- #
141
- # @return [ Array ] The aggregate write errors.
142
- #
143
- # @since 2.0.0
144
- def aggregate_write_errors
145
- @replies.each_with_index.reduce(nil) do |errors, (reply, i)|
146
- if reply_write_errors?(reply)
147
- errors ||= []
148
- errors << { 'errmsg' => reply.documents.first[Error::ERROR],
149
- 'index' => indexes[i],
150
- 'code' => reply.documents.first[Error::CODE] }
151
- end
152
- errors
153
- end
154
- end
155
-
156
- # Aggregate the write concern errors returned from this result.
157
- #
158
- # @example Aggregate the write concern errors.
159
- # result.aggregate_write_concern_errors
160
- #
161
- # @return [ Array ] The aggregate write concern errors.
162
- #
163
- # @since 2.0.0
164
- def aggregate_write_concern_errors
165
- @replies.each_with_index.reduce(nil) do |errors, (reply, i)|
166
- # @todo: only raise if error is timeout
167
- if error = reply_write_errors?(reply)
168
- errors ||= []
169
- note = reply.documents.first['wnote'] || reply.documents.first['jnote']
170
- if note
171
- code = reply.documents.first['code'] || "bad value constant"
172
- error_string = "#{code}: #{note}"
173
- else
174
- code = reply.documents.first['code'] || "unknown error constant"
175
- error_string = "#{code}: #{error}"
176
- end
177
- errors << { 'errmsg' => error_string,
178
- 'index' => indexes[i],
179
- 'code' => code }
180
- end
181
- errors
182
- end
183
- end
184
-
185
- private
186
-
187
- def reply_write_errors?(reply)
188
- reply.documents.first[Error::ERROR] ||
189
- reply.documents.first[Error::ERRMSG]
190
- end
191
61
  end
192
62
  end
193
63
  end