mongo 2.9.2 → 2.10.0.rc0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/lib/mongo.rb +1 -0
- data/lib/mongo/auth/user/view.rb +4 -4
- data/lib/mongo/bulk_write.rb +14 -8
- data/lib/mongo/bulk_write/result.rb +1 -1
- data/lib/mongo/bulk_write/result_combiner.rb +2 -2
- data/lib/mongo/bulk_write/transformable.rb +17 -9
- data/lib/mongo/client.rb +107 -16
- data/lib/mongo/cluster.rb +47 -25
- data/lib/mongo/cluster/topology/replica_set_no_primary.rb +1 -1
- data/lib/mongo/cluster_time.rb +139 -0
- data/lib/mongo/collection.rb +84 -25
- data/lib/mongo/collection/view.rb +7 -3
- data/lib/mongo/collection/view/aggregation.rb +4 -4
- data/lib/mongo/collection/view/builder/aggregation.rb +31 -6
- data/lib/mongo/collection/view/builder/find_command.rb +4 -1
- data/lib/mongo/collection/view/builder/map_reduce.rb +4 -1
- data/lib/mongo/collection/view/change_stream.rb +54 -66
- data/lib/mongo/collection/view/iterable.rb +2 -2
- data/lib/mongo/collection/view/map_reduce.rb +6 -4
- data/lib/mongo/collection/view/readable.rb +36 -16
- data/lib/mongo/collection/view/writable.rb +68 -22
- data/lib/mongo/cursor.rb +87 -20
- data/lib/mongo/database.rb +47 -43
- data/lib/mongo/database/view.rb +54 -11
- data/lib/mongo/error.rb +13 -4
- data/lib/mongo/error/invalid_write_concern.rb +2 -2
- data/lib/mongo/error/operation_failure.rb +65 -11
- data/lib/mongo/error/parser.rb +41 -8
- data/lib/mongo/grid/fs_bucket.rb +26 -6
- data/lib/mongo/grid/stream/read.rb +9 -2
- data/lib/mongo/grid/stream/write.rb +21 -5
- data/lib/mongo/index/view.rb +3 -3
- data/lib/mongo/lint.rb +10 -3
- data/lib/mongo/operation.rb +2 -0
- data/lib/mongo/operation/aggregate/result.rb +19 -6
- data/lib/mongo/operation/collections_info.rb +1 -1
- data/lib/mongo/operation/get_more/result.rb +9 -0
- data/lib/mongo/operation/list_collections/command.rb +1 -3
- data/lib/mongo/operation/list_collections/op_msg.rb +1 -2
- data/lib/mongo/operation/parallel_scan/command.rb +4 -1
- data/lib/mongo/operation/parallel_scan/op_msg.rb +4 -1
- data/lib/mongo/operation/result.rb +27 -4
- data/lib/mongo/operation/shared/executable.rb +19 -5
- data/lib/mongo/operation/shared/executable_no_validate.rb +1 -2
- data/lib/mongo/operation/shared/executable_transaction_label.rb +0 -9
- data/lib/mongo/operation/shared/polymorphic_result.rb +9 -1
- data/lib/mongo/operation/shared/result/aggregatable.rb +2 -2
- data/lib/mongo/operation/shared/sessions_supported.rb +42 -32
- data/lib/mongo/operation/shared/specifiable.rb +40 -0
- data/lib/mongo/operation/shared/unpinnable.rb +39 -0
- data/lib/mongo/operation/shared/write.rb +1 -1
- data/lib/mongo/protocol/update.rb +6 -2
- data/lib/mongo/retryable.rb +79 -39
- data/lib/mongo/server/connection.rb +10 -3
- data/lib/mongo/server/description.rb +25 -1
- data/lib/mongo/server/monitor/connection.rb +1 -1
- data/lib/mongo/server_selector.rb +10 -0
- data/lib/mongo/server_selector/selectable.rb +172 -32
- data/lib/mongo/session.rb +654 -581
- data/lib/mongo/session/session_pool.rb +1 -1
- data/lib/mongo/socket.rb +7 -28
- data/lib/mongo/socket/ssl.rb +26 -1
- data/lib/mongo/socket/tcp.rb +3 -0
- data/lib/mongo/socket/unix.rb +3 -0
- data/lib/mongo/uri.rb +112 -265
- data/lib/mongo/uri/srv_protocol.rb +4 -1
- data/lib/mongo/version.rb +1 -1
- data/lib/mongo/write_concern.rb +10 -29
- data/lib/mongo/write_concern/acknowledged.rb +12 -0
- data/lib/mongo/write_concern/base.rb +17 -13
- data/lib/mongo/write_concern/unacknowledged.rb +12 -0
- data/spec/atlas/atlas_connectivity_spec.rb +7 -37
- data/spec/atlas/operations_spec.rb +25 -0
- data/spec/integration/change_stream_examples_spec.rb +45 -31
- data/spec/integration/change_stream_spec.rb +305 -5
- data/spec/integration/client_spec.rb +44 -0
- data/spec/integration/command_monitoring_spec.rb +1 -0
- data/spec/integration/command_spec.rb +7 -1
- data/spec/integration/mmapv1_spec.rb +28 -0
- data/spec/integration/mongos_pinning_spec.rb +34 -0
- data/spec/integration/operation_failure_code_spec.rb +2 -2
- data/spec/integration/{read_concern.rb → read_concern_spec.rb} +7 -1
- data/spec/integration/read_preference_spec.rb +485 -0
- data/spec/integration/retryable_writes_spec.rb +8 -19
- data/spec/integration/sdam_error_handling_spec.rb +1 -1
- data/spec/integration/sdam_events_spec.rb +2 -2
- data/spec/integration/server_description_spec.rb +14 -17
- data/spec/integration/server_selector_spec.rb +7 -3
- data/spec/integration/server_spec.rb +48 -0
- data/spec/integration/ssl_uri_options_spec.rb +1 -1
- data/spec/integration/step_down_spec.rb +10 -4
- data/spec/integration/transactions_examples_spec.rb +11 -10
- data/spec/lite_spec_helper.rb +19 -16
- data/spec/mongo/auth/scram/negotiation_spec.rb +11 -8
- data/spec/mongo/bulk_write/ordered_combiner_spec.rb +6 -6
- data/spec/mongo/bulk_write/unordered_combiner_spec.rb +4 -4
- data/spec/mongo/bulk_write_spec.rb +12 -2
- data/spec/mongo/client_construction_spec.rb +160 -8
- data/spec/mongo/client_spec.rb +5 -4
- data/spec/mongo/cluster_spec.rb +6 -6
- data/spec/mongo/cluster_time_spec.rb +148 -0
- data/spec/mongo/collection/view/aggregation_spec.rb +34 -15
- data/spec/mongo/collection/view/change_stream_spec.rb +62 -3
- data/spec/mongo/collection/view/map_reduce_spec.rb +7 -5
- data/spec/mongo/collection/view/readable_spec.rb +4 -4
- data/spec/mongo/collection_spec.rb +331 -14
- data/spec/mongo/cursor_spec.rb +117 -5
- data/spec/mongo/database_spec.rb +240 -8
- data/spec/mongo/error/operation_failure_spec.rb +47 -1
- data/spec/mongo/error/parser_spec.rb +160 -23
- data/spec/mongo/operation/insert/bulk_spec.rb +2 -1
- data/spec/mongo/operation/result_spec.rb +27 -0
- data/spec/mongo/operation/update/bulk_spec.rb +1 -0
- data/spec/mongo/retryable_spec.rb +2 -0
- data/spec/mongo/server/app_metadata_spec.rb +2 -2
- data/spec/mongo/server/connection_spec.rb +13 -17
- data/spec/mongo/server/monitor/connection_spec.rb +13 -10
- data/spec/mongo/server_selector_spec.rb +34 -2
- data/spec/mongo/session/session_pool_spec.rb +14 -3
- data/spec/mongo/session_spec.rb +3 -3
- data/spec/mongo/session_transaction_spec.rb +4 -3
- data/spec/mongo/socket/ssl_spec.rb +19 -5
- data/spec/mongo/socket_spec.rb +1 -62
- data/spec/mongo/uri/srv_protocol_spec.rb +14 -20
- data/spec/mongo/uri_option_parsing_spec.rb +94 -8
- data/spec/mongo/uri_spec.rb +23 -10
- data/spec/mongo/write_concern_spec.rb +56 -3
- data/spec/spec_tests/change_streams_spec.rb +2 -1
- data/spec/spec_tests/cmap_spec.rb +1 -1
- data/spec/spec_tests/crud_spec.rb +12 -2
- data/spec/spec_tests/data/change_streams/change-streams-errors.yml +24 -1
- data/spec/spec_tests/data/change_streams/change-streams.yml +172 -3
- data/spec/spec_tests/data/command_monitoring/bulkWrite.yml +1 -1
- data/spec/spec_tests/data/command_monitoring/updateMany.yml +0 -2
- data/spec/spec_tests/data/command_monitoring/updateOne.yml +0 -5
- data/spec/spec_tests/data/crud/read/aggregate-out.yml +0 -6
- data/spec/spec_tests/data/crud/read/count-empty.yml +29 -0
- data/spec/spec_tests/data/crud/write/bulkWrite-arrayFilters.yml +1 -0
- data/spec/spec_tests/data/crud/write/bulkWrite-collation.yml +101 -0
- data/spec/spec_tests/data/crud/write/bulkWrite.yml +401 -0
- data/spec/spec_tests/data/crud/write/insertMany.yml +58 -2
- data/spec/spec_tests/data/crud/write/updateMany-arrayFilters.yml +3 -0
- data/spec/spec_tests/data/crud/write/updateOne-arrayFilters.yml +6 -1
- data/spec/spec_tests/data/crud_v2/aggregate-merge.yml +103 -0
- data/spec/spec_tests/data/crud_v2/aggregate-out-readConcern.yml +110 -0
- data/spec/spec_tests/data/crud_v2/bulkWrite-arrayFilters.yml +81 -0
- data/spec/spec_tests/data/crud_v2/db-aggregate.yml +38 -0
- data/spec/spec_tests/data/crud_v2/updateWithPipelines.yml +92 -0
- data/spec/spec_tests/data/retryable_writes/insertOne-serverErrors.yml +2 -2
- data/spec/spec_tests/data/transactions/abort.yml +3 -0
- data/spec/spec_tests/data/transactions/bulk.yml +3 -8
- data/spec/spec_tests/data/transactions/causal-consistency.yml +3 -8
- data/spec/spec_tests/data/transactions/commit.yml +3 -1
- data/spec/spec_tests/data/transactions/count.yml +3 -0
- data/spec/spec_tests/data/transactions/delete.yml +3 -0
- data/spec/spec_tests/data/transactions/error-labels.yml +4 -1
- data/spec/spec_tests/data/transactions/errors-client.yml +56 -0
- data/spec/spec_tests/data/transactions/errors.yml +3 -0
- data/spec/spec_tests/data/transactions/findOneAndDelete.yml +3 -0
- data/spec/spec_tests/data/transactions/findOneAndReplace.yml +3 -0
- data/spec/spec_tests/data/transactions/findOneAndUpdate.yml +3 -0
- data/spec/spec_tests/data/transactions/insert.yml +3 -0
- data/spec/spec_tests/data/transactions/isolation.yml +3 -0
- data/spec/spec_tests/data/transactions/mongos-pin-auto.yml +1671 -0
- data/spec/spec_tests/data/transactions/mongos-recovery-token.yml +347 -0
- data/spec/spec_tests/data/transactions/pin-mongos.yml +557 -0
- data/spec/spec_tests/data/transactions/read-concern.yml +3 -0
- data/spec/spec_tests/data/transactions/read-pref.yml +3 -0
- data/spec/spec_tests/data/transactions/reads.yml +3 -0
- data/spec/spec_tests/data/transactions/retryable-abort.yml +5 -2
- data/spec/spec_tests/data/transactions/retryable-commit.yml +4 -1
- data/spec/spec_tests/data/transactions/retryable-writes.yml +3 -0
- data/spec/spec_tests/data/transactions/run-command.yml +3 -0
- data/spec/spec_tests/data/transactions/transaction-options.yml +6 -0
- data/spec/spec_tests/data/transactions/update.yml +3 -8
- data/spec/spec_tests/data/transactions/write-concern.yml +348 -38
- data/spec/spec_tests/data/transactions_api/callback-aborts.yml +6 -0
- data/spec/spec_tests/data/transactions_api/callback-commits.yml +5 -0
- data/spec/spec_tests/data/transactions_api/callback-retry.yml +7 -2
- data/spec/spec_tests/data/transactions_api/commit-retry.yml +70 -15
- data/spec/spec_tests/data/transactions_api/commit-transienttransactionerror-4.2.yml +3 -0
- data/spec/spec_tests/data/transactions_api/commit-transienttransactionerror.yml +3 -0
- data/spec/spec_tests/data/transactions_api/commit-writeconcernerror.yml +59 -109
- data/spec/spec_tests/data/transactions_api/commit.yml +5 -0
- data/spec/spec_tests/data/transactions_api/transaction-options.yml +10 -0
- data/spec/spec_tests/retryable_reads_spec.rb +5 -2
- data/spec/spec_tests/retryable_writes_spec.rb +5 -2
- data/spec/spec_tests/sdam_monitoring_spec.rb +3 -3
- data/spec/spec_tests/sdam_spec.rb +2 -2
- data/spec/spec_tests/transactions_api_spec.rb +1 -67
- data/spec/spec_tests/transactions_spec.rb +2 -66
- data/spec/support/authorization.rb +4 -0
- data/spec/support/change_streams.rb +30 -10
- data/spec/support/change_streams/operation.rb +27 -0
- data/spec/support/client_registry.rb +44 -25
- data/spec/support/cluster_config.rb +25 -14
- data/spec/support/cluster_tools.rb +32 -10
- data/spec/support/command_monitoring.rb +1 -1
- data/spec/support/common_shortcuts.rb +30 -0
- data/spec/support/connection_string.rb +8 -3
- data/spec/support/constraints.rb +34 -0
- data/spec/support/crud.rb +31 -16
- data/spec/support/crud/context.rb +23 -0
- data/spec/support/crud/operation.rb +311 -14
- data/spec/support/crud/spec.rb +2 -1
- data/spec/support/crud/test.rb +24 -27
- data/spec/support/crud/test_base.rb +22 -0
- data/spec/support/crud/verifier.rb +15 -1
- data/spec/support/event_subscriber.rb +12 -0
- data/spec/support/sdam_formatter_integration.rb +12 -6
- data/spec/support/shared/server_selector.rb +10 -0
- data/spec/support/shared/session.rb +13 -12
- data/spec/support/spec_config.rb +32 -22
- data/spec/support/spec_setup.rb +2 -2
- data/spec/support/transactions.rb +87 -0
- data/spec/support/transactions/context.rb +33 -0
- data/spec/support/transactions/operation.rb +99 -349
- data/spec/support/transactions/spec.rb +1 -3
- data/spec/support/transactions/test.rb +110 -49
- data/spec/support/utils.rb +74 -1
- metadata +52 -10
- metadata.gz.sig +0 -0
- data/spec/support/crud/read.rb +0 -265
- data/spec/support/crud/write.rb +0 -284
@@ -34,7 +34,15 @@ module Mongo
|
|
34
34
|
#
|
35
35
|
# @param [ Hash ] opts The options.
|
36
36
|
#
|
37
|
+
# @option opts [ Integer ] :max_time_ms The maximum amount of time to allow the command
|
38
|
+
# to run in milliseconds.
|
39
|
+
# @option opts [ Hash ] :projection The fields to include or exclude in the returned doc.
|
40
|
+
# @option opts [ Hash ] :sort The key and direction pairs by which the result set
|
41
|
+
# will be sorted.
|
42
|
+
# @option opts [ Hash ] :write_concern The write concern options.
|
43
|
+
# Defaults to the collection's write concern.
|
37
44
|
# @option opts [ Hash ] :collation The collation to use.
|
45
|
+
# @option opts [ Session ] :session The session to use.
|
38
46
|
#
|
39
47
|
# @return [ BSON::Document, nil ] The document, if found.
|
40
48
|
#
|
@@ -44,10 +52,11 @@ module Mongo
|
|
44
52
|
cmd[:fields] = projection if projection
|
45
53
|
cmd[:sort] = sort if sort
|
46
54
|
cmd[:maxTimeMS] = max_time_ms if max_time_ms
|
47
|
-
cmd[:writeConcern] = write_concern.options if write_concern
|
48
55
|
|
49
56
|
with_session(opts) do |session|
|
50
|
-
|
57
|
+
applied_write_concern = applied_write_concern(session)
|
58
|
+
cmd[:writeConcern] = applied_write_concern.options if applied_write_concern
|
59
|
+
write_with_retry(session, applied_write_concern) do |server, txn_num|
|
51
60
|
apply_collation!(cmd, server, opts)
|
52
61
|
Operation::Command.new(
|
53
62
|
:selector => cmd,
|
@@ -93,6 +102,11 @@ module Mongo
|
|
93
102
|
# @param [ BSON::Document ] document The updates.
|
94
103
|
# @param [ Hash ] opts The options.
|
95
104
|
#
|
105
|
+
# @option options [ Integer ] :max_time_ms The maximum amount of time to allow the command
|
106
|
+
# to run in milliseconds.
|
107
|
+
# @option opts [ Hash ] :projection The fields to include or exclude in the returned doc.
|
108
|
+
# @option opts [ Hash ] :sort The key and direction pairs by which the result set
|
109
|
+
# will be sorted.
|
96
110
|
# @option opts [ Symbol ] :return_document Either :before or :after.
|
97
111
|
# @option opts [ true, false ] :upsert Whether to upsert if the document doesn't exist.
|
98
112
|
# @option opts [ true, false ] :bypass_document_validation Whether or
|
@@ -102,6 +116,7 @@ module Mongo
|
|
102
116
|
# @option opts [ Hash ] :collation The collation to use.
|
103
117
|
# @option opts [ Array ] :array_filters A set of filters specifying to which array elements
|
104
118
|
# an update should apply.
|
119
|
+
# @option opts [ Session ] :session The session to use.
|
105
120
|
#
|
106
121
|
# @return [ BSON::Document ] The document.
|
107
122
|
#
|
@@ -115,10 +130,11 @@ module Mongo
|
|
115
130
|
cmd[:upsert] = opts[:upsert] if opts[:upsert]
|
116
131
|
cmd[:maxTimeMS] = max_time_ms if max_time_ms
|
117
132
|
cmd[:bypassDocumentValidation] = !!opts[:bypass_document_validation]
|
118
|
-
cmd[:writeConcern] = write_concern.options if write_concern
|
119
133
|
|
120
134
|
value = with_session(opts) do |session|
|
121
|
-
|
135
|
+
applied_write_concern = applied_write_concern(opts[:session])
|
136
|
+
cmd[:writeConcern] = applied_write_concern.options if applied_write_concern
|
137
|
+
write_with_retry(session, applied_write_concern) do |server, txn_num|
|
122
138
|
apply_collation!(cmd, server, opts)
|
123
139
|
apply_array_filters!(cmd, server, opts)
|
124
140
|
Operation::Command.new(
|
@@ -140,6 +156,7 @@ module Mongo
|
|
140
156
|
# @param [ Hash ] opts The options.
|
141
157
|
#
|
142
158
|
# @option opts [ Hash ] :collation The collation to use.
|
159
|
+
# @option opts [ Session ] :session The session to use.
|
143
160
|
#
|
144
161
|
# @return [ Result ] The response from the database.
|
145
162
|
#
|
@@ -147,13 +164,14 @@ module Mongo
|
|
147
164
|
def delete_many(opts = {})
|
148
165
|
delete_doc = { Operation::Q => filter, Operation::LIMIT => 0 }
|
149
166
|
with_session(opts) do |session|
|
150
|
-
|
167
|
+
write_concern = write_concern_with_session(session)
|
168
|
+
nro_write_with_retry(session, write_concern) do |server|
|
151
169
|
apply_collation!(delete_doc, server, opts)
|
152
170
|
Operation::Delete.new(
|
153
171
|
:deletes => [ delete_doc ],
|
154
172
|
:db_name => collection.database.name,
|
155
173
|
:coll_name => collection.name,
|
156
|
-
:write_concern =>
|
174
|
+
:write_concern => write_concern,
|
157
175
|
:session => session
|
158
176
|
).execute(server)
|
159
177
|
end
|
@@ -168,14 +186,15 @@ module Mongo
|
|
168
186
|
# @param [ Hash ] opts The options.
|
169
187
|
#
|
170
188
|
# @option opts [ Hash ] :collation The collation to use.
|
189
|
+
# @option opts [ Session ] :session The session to use.
|
171
190
|
#
|
172
191
|
# @return [ Result ] The response from the database.
|
173
192
|
#
|
174
193
|
# @since 2.0.0
|
175
194
|
def delete_one(opts = {})
|
176
195
|
delete_doc = { Operation::Q => filter, Operation::LIMIT => 1 }
|
177
|
-
write_concern = collection.write_concern
|
178
196
|
with_session(opts) do |session|
|
197
|
+
write_concern = write_concern_with_session(session)
|
179
198
|
write_with_retry(session, write_concern) do |server, txn_num|
|
180
199
|
apply_collation!(delete_doc, server, opts)
|
181
200
|
Operation::Delete.new(
|
@@ -200,7 +219,10 @@ module Mongo
|
|
200
219
|
#
|
201
220
|
# @option opts [ true, false ] :upsert Whether to upsert if the
|
202
221
|
# document doesn't exist.
|
222
|
+
# @option opts [ true, false ] :bypass_document_validation Whether or
|
223
|
+
# not to skip document level validation.
|
203
224
|
# @option opts [ Hash ] :collation The collation to use.
|
225
|
+
# @option opts [ Session ] :session The session to use.
|
204
226
|
#
|
205
227
|
# @return [ Result ] The response from the database.
|
206
228
|
#
|
@@ -208,11 +230,12 @@ module Mongo
|
|
208
230
|
def replace_one(replacement, opts = {})
|
209
231
|
update_doc = { Operation::Q => filter,
|
210
232
|
Operation::U => replacement,
|
211
|
-
Operation::MULTI => false,
|
212
|
-
Operation::UPSERT => !!opts[:upsert]
|
213
233
|
}
|
214
|
-
|
234
|
+
if opts[:upsert]
|
235
|
+
update_doc[:upsert] = true
|
236
|
+
end
|
215
237
|
with_session(opts) do |session|
|
238
|
+
write_concern = write_concern_with_session(session)
|
216
239
|
write_with_retry(session, write_concern) do |server, txn_num|
|
217
240
|
apply_collation!(update_doc, server, opts)
|
218
241
|
apply_array_filters!(update_doc, server, opts)
|
@@ -235,14 +258,17 @@ module Mongo
|
|
235
258
|
# @example Update multiple documents in the collection.
|
236
259
|
# collection_view.update_many('$set' => { name: 'test' })
|
237
260
|
#
|
238
|
-
# @param [ Hash ] spec The update
|
261
|
+
# @param [ Hash | Array<Hash> ] spec The update document or pipeline.
|
239
262
|
# @param [ Hash ] opts The options.
|
240
263
|
#
|
241
264
|
# @option opts [ true, false ] :upsert Whether to upsert if the
|
242
265
|
# document doesn't exist.
|
266
|
+
# @option opts [ true, false ] :bypass_document_validation Whether or
|
267
|
+
# not to skip document level validation.
|
243
268
|
# @option opts [ Hash ] :collation The collation to use.
|
244
|
-
# @option opts [ Array ] :array_filters A set of filters specifying to
|
245
|
-
# an update should apply.
|
269
|
+
# @option opts [ Array ] :array_filters A set of filters specifying to
|
270
|
+
# which array elements an update should apply.
|
271
|
+
# @option opts [ Session ] :session The session to use.
|
246
272
|
#
|
247
273
|
# @return [ Result ] The response from the database.
|
248
274
|
#
|
@@ -251,16 +277,20 @@ module Mongo
|
|
251
277
|
update_doc = { Operation::Q => filter,
|
252
278
|
Operation::U => spec,
|
253
279
|
Operation::MULTI => true,
|
254
|
-
|
280
|
+
}
|
281
|
+
if opts[:upsert]
|
282
|
+
update_doc[:upsert] = true
|
283
|
+
end
|
255
284
|
with_session(opts) do |session|
|
256
|
-
|
285
|
+
write_concern = write_concern_with_session(session)
|
286
|
+
nro_write_with_retry(session, write_concern) do |server|
|
257
287
|
apply_collation!(update_doc, server, opts)
|
258
288
|
apply_array_filters!(update_doc, server, opts)
|
259
289
|
Operation::Update.new(
|
260
290
|
:updates => [ update_doc ],
|
261
291
|
:db_name => collection.database.name,
|
262
292
|
:coll_name => collection.name,
|
263
|
-
:write_concern =>
|
293
|
+
:write_concern => write_concern,
|
264
294
|
:bypass_document_validation => !!opts[:bypass_document_validation],
|
265
295
|
:session => session
|
266
296
|
).execute(server)
|
@@ -273,14 +303,17 @@ module Mongo
|
|
273
303
|
# @example Update a single document in the collection.
|
274
304
|
# collection_view.update_one('$set' => { name: 'test' })
|
275
305
|
#
|
276
|
-
# @param [ Hash ] spec The update
|
306
|
+
# @param [ Hash | Array<Hash> ] spec The update document or pipeline.
|
277
307
|
# @param [ Hash ] opts The options.
|
278
308
|
#
|
279
309
|
# @option opts [ true, false ] :upsert Whether to upsert if the
|
280
310
|
# document doesn't exist.
|
311
|
+
# @option opts [ true, false ] :bypass_document_validation Whether or
|
312
|
+
# not to skip document level validation.
|
281
313
|
# @option opts [ Hash ] :collation The collation to use.
|
282
|
-
# @option opts [ Array ] :array_filters A set of filters specifying to
|
283
|
-
# an update should apply.
|
314
|
+
# @option opts [ Array ] :array_filters A set of filters specifying to
|
315
|
+
# which array elements an update should apply.
|
316
|
+
# @option opts [ Session ] :session The session to use.
|
284
317
|
#
|
285
318
|
# @return [ Result ] The response from the database.
|
286
319
|
#
|
@@ -288,10 +321,12 @@ module Mongo
|
|
288
321
|
def update_one(spec, opts = {})
|
289
322
|
update_doc = { Operation::Q => filter,
|
290
323
|
Operation::U => spec,
|
291
|
-
|
292
|
-
|
293
|
-
|
324
|
+
}
|
325
|
+
if opts[:upsert]
|
326
|
+
update_doc[:upsert] = true
|
327
|
+
end
|
294
328
|
with_session(opts) do |session|
|
329
|
+
write_concern = write_concern_with_session(session)
|
295
330
|
write_with_retry(session, write_concern) do |server, txn_num|
|
296
331
|
apply_collation!(update_doc, server, opts)
|
297
332
|
apply_array_filters!(update_doc, server, opts)
|
@@ -323,6 +358,17 @@ module Mongo
|
|
323
358
|
raise Error::UnsupportedArrayFilters.new
|
324
359
|
end
|
325
360
|
end
|
361
|
+
|
362
|
+
# Get the write concern for an operation
|
363
|
+
#
|
364
|
+
# @return [ Mongo::WriteConcern ] The write concern.
|
365
|
+
def applied_write_concern(session)
|
366
|
+
if wco = options[:write_concern] || options[:write]
|
367
|
+
WriteConcern.get(wco)
|
368
|
+
else
|
369
|
+
write_concern_with_session(session)
|
370
|
+
end
|
371
|
+
end
|
326
372
|
end
|
327
373
|
end
|
328
374
|
end
|
data/lib/mongo/cursor.rb
CHANGED
@@ -42,6 +42,12 @@ module Mongo
|
|
42
42
|
# @return [ Collection::View ] view The collection view.
|
43
43
|
attr_reader :view
|
44
44
|
|
45
|
+
# The resume token tracked by the cursor for change stream resuming
|
46
|
+
#
|
47
|
+
# @return [ BSON::Document | nil ] The cursor resume token.
|
48
|
+
# @api private
|
49
|
+
attr_reader :resume_token
|
50
|
+
|
45
51
|
# Creates a +Cursor+ object.
|
46
52
|
#
|
47
53
|
# @example Instantiate the cursor.
|
@@ -125,20 +131,39 @@ module Mongo
|
|
125
131
|
#
|
126
132
|
# @since 2.0.0
|
127
133
|
def each
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
134
|
+
# If we already iterated past the first batch (i.e., called get_more
|
135
|
+
# at least once), the cursor on the server side has advanced past
|
136
|
+
# the first batch and restarting iteration from the beginning by
|
137
|
+
# returning initial result would miss documents in the second batch
|
138
|
+
# and subsequent batches up to wherever the cursor is. Detect this
|
139
|
+
# condition and abort the iteration.
|
140
|
+
#
|
141
|
+
# In a future driver version, each would either continue from the
|
142
|
+
# end of previous iteration or would always restart from the
|
143
|
+
# beginning.
|
144
|
+
if @get_more_called
|
145
|
+
raise NotImplementedError, 'Cannot restart iteration of a cursor which issued a getMore'
|
132
146
|
end
|
147
|
+
|
148
|
+
# To maintain compatibility with pre-2.10 driver versions, reset
|
149
|
+
# the documents array each time a new iteration is started.
|
150
|
+
@documents = nil
|
151
|
+
|
152
|
+
loop do
|
153
|
+
document = try_next
|
154
|
+
yield document if document
|
155
|
+
end
|
156
|
+
rescue StopIteration => e
|
157
|
+
return self
|
133
158
|
end
|
134
159
|
|
135
160
|
# Return one document from the query, if one is available.
|
136
161
|
#
|
137
|
-
# Retries once on a resumable error.
|
138
|
-
#
|
139
162
|
# This method will wait up to max_await_time_ms milliseconds
|
140
163
|
# for changes from the server, and if no changes are received
|
141
|
-
# it will return nil.
|
164
|
+
# it will return nil. If there are no more documents to return
|
165
|
+
# from the server, or if we have exhausted the cursor, it will
|
166
|
+
# raise a StopIteration exception.
|
142
167
|
#
|
143
168
|
# @note This method is experimental and subject to change.
|
144
169
|
#
|
@@ -146,30 +171,45 @@ module Mongo
|
|
146
171
|
# @api private
|
147
172
|
def try_next
|
148
173
|
if @documents.nil?
|
149
|
-
|
174
|
+
# Since published versions of Mongoid have a copy of old driver cursor
|
175
|
+
# code, our dup call in #process isn't invoked when Mongoid query
|
176
|
+
# cache is active. Work around that by also calling dup here on
|
177
|
+
# the result of #process which might come out of Mongoid's code.
|
178
|
+
@documents = process(@initial_result).dup
|
150
179
|
# the documents here can be an empty array, hence
|
151
180
|
# we may end up issuing a getMore in the first try_next call
|
152
181
|
end
|
153
182
|
|
154
183
|
if @documents.empty?
|
184
|
+
# On empty batches, we cache the batch resume token
|
185
|
+
cache_batch_resume_token
|
186
|
+
|
155
187
|
if more?
|
156
188
|
if exhausted?
|
157
189
|
kill_cursors
|
158
|
-
|
190
|
+
raise StopIteration
|
159
191
|
end
|
160
|
-
|
161
192
|
@documents = get_more
|
193
|
+
else
|
194
|
+
raise StopIteration
|
162
195
|
end
|
163
196
|
else
|
164
197
|
# cursor is closed here
|
165
198
|
# keep documents as an empty array
|
166
199
|
end
|
167
200
|
|
168
|
-
|
169
|
-
|
201
|
+
# If there is at least one document, cache its _id
|
202
|
+
if @documents[0]
|
203
|
+
cache_resume_token(@documents[0])
|
170
204
|
end
|
171
205
|
|
172
|
-
|
206
|
+
# Cache the batch resume token if we are iterating
|
207
|
+
# over the last document, or if the batch is empty
|
208
|
+
if @documents.size <= 1
|
209
|
+
cache_batch_resume_token
|
210
|
+
end
|
211
|
+
|
212
|
+
return @documents.shift
|
173
213
|
end
|
174
214
|
|
175
215
|
# Get the batch size.
|
@@ -235,13 +275,15 @@ module Mongo
|
|
235
275
|
use_limit? ? @remaining : (batch_size || 0)
|
236
276
|
end
|
237
277
|
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
278
|
+
# Execute a getMore command and return the batch of documents
|
279
|
+
# obtained from the server.
|
280
|
+
#
|
281
|
+
# @return [ Array<BSON::Document> ] The batch of documents
|
282
|
+
#
|
283
|
+
# @api private
|
244
284
|
def get_more
|
285
|
+
@get_more_called = true
|
286
|
+
|
245
287
|
# Modern retryable reads specification prohibits retrying getMores.
|
246
288
|
# Legacy retryable read logic used to retry getMores, but since
|
247
289
|
# doing so may result in silent data loss, the driver no longer retries
|
@@ -250,6 +292,22 @@ module Mongo
|
|
250
292
|
process(get_more_operation.execute(@server))
|
251
293
|
end
|
252
294
|
|
295
|
+
private
|
296
|
+
|
297
|
+
def exhausted?
|
298
|
+
limited? ? @remaining <= 0 : false
|
299
|
+
end
|
300
|
+
|
301
|
+
def cache_resume_token(doc)
|
302
|
+
if doc[:_id] && doc[:_id].is_a?(Hash)
|
303
|
+
@resume_token = doc[:_id] && doc[:_id].dup.freeze
|
304
|
+
end
|
305
|
+
end
|
306
|
+
|
307
|
+
def cache_batch_resume_token
|
308
|
+
@resume_token = @post_batch_resume_token if @post_batch_resume_token
|
309
|
+
end
|
310
|
+
|
253
311
|
def get_more_operation
|
254
312
|
if @server.features.find_command_enabled?
|
255
313
|
spec = Builder::GetMoreCommand.new(self, @session).specification
|
@@ -298,8 +356,17 @@ module Mongo
|
|
298
356
|
@coll_name ||= result.namespace.sub("#{database.name}.", '') if result.namespace
|
299
357
|
unregister if result.cursor_id == 0
|
300
358
|
@cursor_id = result.cursor_id
|
359
|
+
|
360
|
+
if result.respond_to?(:post_batch_resume_token)
|
361
|
+
@post_batch_resume_token = result.post_batch_resume_token
|
362
|
+
end
|
363
|
+
|
301
364
|
end_session if !more?
|
302
|
-
|
365
|
+
|
366
|
+
# Since our iteration code mutates the documents array by calling #shift
|
367
|
+
# on it, duplicate the documents here to permit restarting iteration
|
368
|
+
# from the beginning of the cursor as long as get_more was not called
|
369
|
+
result.documents.dup
|
303
370
|
end
|
304
371
|
|
305
372
|
def use_limit?
|
data/lib/mongo/database.rb
CHANGED
@@ -42,6 +42,7 @@ module Mongo
|
|
42
42
|
# Database name field constant.
|
43
43
|
#
|
44
44
|
# @since 2.1.0
|
45
|
+
# @deprecated
|
45
46
|
NAME = 'name'.freeze
|
46
47
|
|
47
48
|
# Databases constant.
|
@@ -109,34 +110,36 @@ module Mongo
|
|
109
110
|
|
110
111
|
# Get all the names of the non-system collections in the database.
|
111
112
|
#
|
112
|
-
# @
|
113
|
-
#
|
113
|
+
# @note The set of returned collection names depends on the version of
|
114
|
+
# MongoDB server that fulfills the request.
|
114
115
|
#
|
115
|
-
# @return [ Array<String> ]
|
116
|
+
# @return [ Array<String> ] Names of the collections.
|
116
117
|
#
|
117
118
|
# @since 2.0.0
|
118
119
|
def collection_names(options = {})
|
119
120
|
View.new(self).collection_names(options)
|
120
121
|
end
|
121
122
|
|
122
|
-
# Get info on all the collections in the database.
|
123
|
+
# Get info on all the non-system collections in the database.
|
123
124
|
#
|
124
|
-
# @
|
125
|
-
#
|
125
|
+
# @note The set of collections returned, and the schema of the
|
126
|
+
# information hash per collection, depends on the MongoDB server
|
127
|
+
# version that fulfills the request.
|
126
128
|
#
|
127
|
-
# @return [ Array<Hash> ]
|
129
|
+
# @return [ Array<Hash> ] Array of information hashes, one for each
|
130
|
+
# collection in the database.
|
128
131
|
#
|
129
132
|
# @since 2.0.5
|
130
133
|
def list_collections
|
131
134
|
View.new(self).list_collections
|
132
135
|
end
|
133
136
|
|
134
|
-
# Get all the collections that belong to this database.
|
137
|
+
# Get all the non-system collections that belong to this database.
|
135
138
|
#
|
136
|
-
# @
|
137
|
-
#
|
139
|
+
# @note The set of returned collections depends on the version of
|
140
|
+
# MongoDB server that fulfills the request.
|
138
141
|
#
|
139
|
-
# @return [ Array<Mongo::Collection> ]
|
142
|
+
# @return [ Array<Mongo::Collection> ] The collections.
|
140
143
|
#
|
141
144
|
# @since 2.0.0
|
142
145
|
def collections
|
@@ -156,37 +159,6 @@ module Mongo
|
|
156
159
|
#
|
157
160
|
# @return [ Hash ] The result of the command execution.
|
158
161
|
def command(operation, opts = {})
|
159
|
-
txn_read_pref = if opts[:session] && opts[:session].in_transaction?
|
160
|
-
opts[:session].txn_read_preference
|
161
|
-
else
|
162
|
-
nil
|
163
|
-
end
|
164
|
-
txn_read_pref ||= opts[:read] || ServerSelector::PRIMARY
|
165
|
-
Lint.validate_underscore_read_preference(txn_read_pref)
|
166
|
-
selector = ServerSelector.get(txn_read_pref)
|
167
|
-
|
168
|
-
client.send(:with_session, opts) do |session|
|
169
|
-
server = selector.select_server(cluster)
|
170
|
-
Operation::Command.new({
|
171
|
-
:selector => operation.dup,
|
172
|
-
:db_name => name,
|
173
|
-
:read => selector,
|
174
|
-
:session => session
|
175
|
-
}).execute(server)
|
176
|
-
end
|
177
|
-
end
|
178
|
-
|
179
|
-
# Execute a read command on the database, retrying the read if necessary.
|
180
|
-
#
|
181
|
-
# @param [ Hash ] operation The command to execute.
|
182
|
-
# @param [ Hash ] opts The command options.
|
183
|
-
#
|
184
|
-
# @option opts :read [ Hash ] The read preference for this command.
|
185
|
-
# @option opts :session [ Session ] The session to use for this command.
|
186
|
-
#
|
187
|
-
# @return [ Hash ] The result of the command execution.
|
188
|
-
# @api private
|
189
|
-
def read_command(operation, opts = {})
|
190
162
|
txn_read_pref = if opts[:session] && opts[:session].in_transaction?
|
191
163
|
opts[:session].txn_read_preference
|
192
164
|
else
|
@@ -228,7 +200,7 @@ module Mongo
|
|
228
200
|
db_name: name,
|
229
201
|
write_concern: write_concern,
|
230
202
|
session: session
|
231
|
-
}).execute(next_primary)
|
203
|
+
}).execute(next_primary(nil, session))
|
232
204
|
end
|
233
205
|
end
|
234
206
|
|
@@ -287,6 +259,38 @@ module Mongo
|
|
287
259
|
Auth::User::View.new(self)
|
288
260
|
end
|
289
261
|
|
262
|
+
# Perform an aggregation on the database.
|
263
|
+
#
|
264
|
+
# @example Perform an aggregation.
|
265
|
+
# collection.aggregate([ { "$listLocalSessions" => {} } ])
|
266
|
+
#
|
267
|
+
# @param [ Array<Hash> ] pipeline The aggregation pipeline.
|
268
|
+
# @param [ Hash ] options The aggregation options.
|
269
|
+
#
|
270
|
+
# @option options [ true, false ] :allow_disk_use Set to true if disk
|
271
|
+
# usage is allowed during the aggregation.
|
272
|
+
# @option options [ Integer ] :batch_size The number of documents to return
|
273
|
+
# per batch.
|
274
|
+
# @option options [ true, false ] :bypass_document_validation Whether or
|
275
|
+
# not to skip document level validation.
|
276
|
+
# @option options [ Hash ] :collation The collation to use.
|
277
|
+
# @option options [ String ] :comment Associate a comment with the aggregation.
|
278
|
+
# @option options [ String ] :hint The index to use for the aggregation.
|
279
|
+
# @option options [ Integer ] :max_time_ms The maximum amount of time in
|
280
|
+
# milliseconds to allow the aggregation to run.
|
281
|
+
# @option options [ true, false ] :use_cursor Indicates whether the command
|
282
|
+
# will request that the server provide results using a cursor. Note that
|
283
|
+
# as of server version 3.6, aggregations always provide results using a
|
284
|
+
# cursor and this option is therefore not valid.
|
285
|
+
# @option options [ Session ] :session The session to use.
|
286
|
+
#
|
287
|
+
# @return [ Aggregation ] The aggregation object.
|
288
|
+
#
|
289
|
+
# @since 2.10.0
|
290
|
+
def aggregate(pipeline, options = {})
|
291
|
+
View.new(self).aggregate(pipeline, options)
|
292
|
+
end
|
293
|
+
|
290
294
|
# As of version 3.6 of the MongoDB server, a ``$changeStream`` pipeline stage is supported
|
291
295
|
# in the aggregation framework. As of version 4.0, this stage allows users to request that
|
292
296
|
# notifications are sent for all changes that occur in the client's database.
|