mongo 2.9.2 → 2.10.0.rc0
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.
- 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.
|