mongo 2.4.3 → 2.5.0.beta
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 +3 -2
- data.tar.gz.sig +0 -0
- data/lib/mongo.rb +3 -2
- data/lib/mongo/auth/cr.rb +6 -4
- data/lib/mongo/auth/cr/conversation.rb +33 -17
- data/lib/mongo/auth/ldap.rb +4 -2
- data/lib/mongo/auth/ldap/conversation.rb +19 -9
- data/lib/mongo/auth/scram.rb +7 -4
- data/lib/mongo/auth/scram/conversation.rb +62 -24
- data/lib/mongo/auth/user.rb +10 -0
- data/lib/mongo/auth/user/view.rb +44 -22
- data/lib/mongo/auth/x509.rb +4 -2
- data/lib/mongo/auth/x509/conversation.rb +19 -9
- data/lib/mongo/bulk_write.rb +33 -27
- data/lib/mongo/bulk_write/combineable.rb +5 -0
- data/lib/mongo/bulk_write/transformable.rb +2 -0
- data/lib/mongo/bulk_write/validatable.rb +4 -0
- data/lib/mongo/client.rb +123 -12
- data/lib/mongo/cluster.rb +52 -11
- data/lib/mongo/cluster/app_metadata.rb +8 -2
- data/lib/mongo/cluster/cursor_reaper.rb +0 -1
- data/lib/mongo/cluster/topology.rb +1 -1
- data/lib/mongo/collection.rb +114 -27
- data/lib/mongo/collection/view.rb +8 -2
- data/lib/mongo/collection/view/aggregation.rb +11 -7
- data/lib/mongo/collection/view/builder/aggregation.rb +5 -1
- data/lib/mongo/collection/view/builder/find_command.rb +5 -3
- data/lib/mongo/collection/view/builder/map_reduce.rb +11 -3
- data/lib/mongo/collection/view/builder/op_query.rb +1 -1
- data/lib/mongo/collection/view/change_stream.rb +160 -0
- data/lib/mongo/collection/view/change_stream/retryable.rb +57 -0
- data/lib/mongo/collection/view/iterable.rb +11 -10
- data/lib/mongo/collection/view/map_reduce.rb +22 -18
- data/lib/mongo/collection/view/readable.rb +51 -37
- data/lib/mongo/collection/view/writable.rb +72 -40
- data/lib/mongo/cursor.rb +25 -4
- data/lib/mongo/cursor/builder/get_more_command.rb +4 -2
- data/lib/mongo/database.rb +22 -11
- data/lib/mongo/database/view.rb +16 -12
- data/lib/mongo/error.rb +5 -0
- data/lib/mongo/error/invalid_session.rb +36 -0
- data/lib/mongo/error/missing_resume_token.rb +39 -0
- data/lib/mongo/error/operation_failure.rb +17 -0
- data/lib/mongo/error/parser.rb +3 -2
- data/lib/mongo/error/unknown_payload_type.rb +41 -0
- data/lib/mongo/error/unsupported_array_filters.rb +51 -0
- data/lib/mongo/error/unsupported_message_type.rb +23 -0
- data/lib/mongo/grid/fs_bucket.rb +5 -4
- data/lib/mongo/grid/stream/read.rb +3 -2
- data/lib/mongo/grid/stream/write.rb +2 -2
- data/lib/mongo/index/view.rb +35 -25
- data/lib/mongo/monitoring/event/secure.rb +14 -0
- data/lib/mongo/operation.rb +16 -0
- data/lib/mongo/operation/commands.rb +1 -0
- data/lib/mongo/operation/commands/aggregate.rb +9 -5
- data/lib/mongo/operation/commands/aggregate/result.rb +1 -1
- data/lib/mongo/operation/commands/collections_info.rb +6 -6
- data/lib/mongo/operation/commands/command.rb +2 -1
- data/lib/mongo/operation/commands/create.rb +6 -2
- data/lib/mongo/operation/commands/drop.rb +6 -2
- data/lib/mongo/operation/commands/drop_database.rb +6 -2
- data/lib/mongo/operation/commands/explain.rb +27 -0
- data/lib/mongo/operation/commands/explain/result.rb +52 -0
- data/lib/mongo/operation/commands/indexes.rb +1 -1
- data/lib/mongo/operation/commands/list_collections.rb +1 -1
- data/lib/mongo/operation/commands/list_collections/result.rb +1 -1
- data/lib/mongo/operation/commands/list_indexes.rb +1 -1
- data/lib/mongo/operation/commands/list_indexes/result.rb +1 -1
- data/lib/mongo/operation/commands/map_reduce.rb +8 -4
- data/lib/mongo/operation/commands/map_reduce/result.rb +13 -1
- data/lib/mongo/operation/commands/user_query.rb +1 -1
- data/lib/mongo/operation/commands/users_info.rb +6 -2
- data/lib/mongo/operation/executable.rb +4 -1
- data/lib/mongo/operation/read_preference.rb +10 -5
- data/lib/mongo/operation/result.rb +26 -2
- data/lib/mongo/operation/specifiable.rb +13 -1
- data/lib/mongo/operation/uses_command_op_msg.rb +47 -0
- data/lib/mongo/operation/write/bulk/bulkable.rb +4 -1
- data/lib/mongo/operation/write/bulk/insert/result.rb +4 -4
- data/lib/mongo/operation/write/command/create_index.rb +6 -1
- data/lib/mongo/operation/write/command/delete.rb +28 -4
- data/lib/mongo/operation/write/command/drop_index.rb +6 -1
- data/lib/mongo/operation/write/command/insert.rb +22 -18
- data/lib/mongo/operation/write/command/update.rb +24 -9
- data/lib/mongo/operation/write/command/writable.rb +14 -1
- data/lib/mongo/operation/write/insert.rb +4 -1
- data/lib/mongo/operation/write/insert/result.rb +2 -2
- data/lib/mongo/operation/write/update.rb +7 -1
- data/lib/mongo/operation/write/write_command_enabled.rb +20 -3
- data/lib/mongo/protocol.rb +3 -0
- data/lib/mongo/protocol/bit_vector.rb +2 -2
- data/lib/mongo/protocol/compressed.rb +135 -0
- data/lib/mongo/protocol/delete.rb +8 -6
- data/lib/mongo/protocol/get_more.rb +8 -6
- data/lib/mongo/protocol/insert.rb +8 -6
- data/lib/mongo/protocol/kill_cursors.rb +8 -6
- data/lib/mongo/protocol/message.rb +31 -3
- data/lib/mongo/protocol/msg.rb +172 -0
- data/lib/mongo/protocol/query.rb +26 -6
- data/lib/mongo/protocol/registry.rb +76 -0
- data/lib/mongo/protocol/reply.rb +10 -5
- data/lib/mongo/protocol/serializers.rb +224 -0
- data/lib/mongo/protocol/update.rb +8 -6
- data/lib/mongo/retryable.rb +4 -2
- data/lib/mongo/server.rb +6 -3
- data/lib/mongo/server/connectable.rb +1 -1
- data/lib/mongo/server/connection.rb +30 -8
- data/lib/mongo/server/description.rb +25 -1
- data/lib/mongo/server/description/features.rb +4 -1
- data/lib/mongo/server/monitor.rb +5 -0
- data/lib/mongo/server/monitor/connection.rb +50 -2
- data/lib/mongo/server_selector/nearest.rb +10 -4
- data/lib/mongo/server_selector/primary.rb +20 -0
- data/lib/mongo/server_selector/primary_preferred.rb +10 -4
- data/lib/mongo/server_selector/secondary.rb +10 -4
- data/lib/mongo/server_selector/secondary_preferred.rb +24 -4
- data/lib/mongo/session.rb +180 -0
- data/lib/mongo/session/server_session.rb +73 -0
- data/lib/mongo/session/session_pool.rb +161 -0
- data/lib/mongo/uri.rb +11 -0
- data/lib/mongo/version.rb +1 -1
- data/mongo.gemspec +2 -1
- data/spec/mongo/auth/cr_spec.rb +12 -0
- data/spec/mongo/auth/ldap_spec.rb +2 -0
- data/spec/mongo/auth/scram/conversation_spec.rb +6 -6
- data/spec/mongo/auth/scram_spec.rb +25 -1
- data/spec/mongo/auth/user/view_spec.rb +268 -76
- data/spec/mongo/auth/x509_spec.rb +2 -0
- data/spec/mongo/bulk_write_spec.rb +435 -5
- data/spec/mongo/client_spec.rb +356 -39
- data/spec/mongo/cluster/app_metadata_spec.rb +2 -2
- data/spec/mongo/cluster_spec.rb +176 -0
- data/spec/mongo/collection/view/aggregation_spec.rb +33 -12
- data/spec/mongo/collection/view/builder/find_command_spec.rb +46 -6
- data/spec/mongo/collection/view/change_stream_spec.rb +814 -0
- data/spec/mongo/collection/view/map_reduce_spec.rb +94 -17
- data/spec/mongo/collection/view/readable_spec.rb +3 -12
- data/spec/mongo/collection_spec.rb +1048 -42
- data/spec/mongo/cursor/builder/get_more_command_spec.rb +19 -0
- data/spec/mongo/cursor_spec.rb +2 -2
- data/spec/mongo/database_spec.rb +50 -1
- data/spec/mongo/grid/fs_bucket_spec.rb +225 -137
- data/spec/mongo/grid/stream/read_spec.rb +2 -2
- data/spec/mongo/index/view_spec.rb +146 -8
- data/spec/mongo/monitoring/event/secure_spec.rb +42 -0
- data/spec/mongo/operation/read/query_spec.rb +2 -1
- data/spec/mongo/operation/specifiable_spec.rb +2 -2
- data/spec/mongo/operation/write/command/delete_spec.rb +96 -13
- data/spec/mongo/operation/write/command/insert_spec.rb +111 -12
- data/spec/mongo/operation/write/command/update_spec.rb +93 -10
- data/spec/mongo/operation/write/delete_spec.rb +1 -1
- data/spec/mongo/operation/write/insert_spec.rb +1 -1
- data/spec/mongo/operation/write/update_spec.rb +1 -1
- data/spec/mongo/protocol/compressed_spec.rb +66 -0
- data/spec/mongo/protocol/delete_spec.rb +14 -0
- data/spec/mongo/protocol/get_more_spec.rb +14 -0
- data/spec/mongo/protocol/insert_spec.rb +14 -0
- data/spec/mongo/protocol/kill_cursors_spec.rb +14 -0
- data/spec/mongo/protocol/msg_spec.rb +499 -0
- data/spec/mongo/protocol/query_spec.rb +45 -0
- data/spec/mongo/protocol/registry_spec.rb +31 -0
- data/spec/mongo/protocol/reply_spec.rb +14 -0
- data/spec/mongo/protocol/update_spec.rb +14 -0
- data/spec/mongo/retryable_spec.rb +6 -2
- data/spec/mongo/sdam_spec.rb +4 -0
- data/spec/mongo/server/connection_spec.rb +4 -2
- data/spec/mongo/server/description_spec.rb +28 -1
- data/spec/mongo/session/server_session_spec.rb +16 -0
- data/spec/mongo/session/session_pool_spec.rb +194 -0
- data/spec/mongo/uri_spec.rb +31 -2
- data/spec/spec_helper.rb +104 -0
- data/spec/support/authorization.rb +6 -1
- data/spec/support/crud.rb +3 -1
- data/spec/support/crud/write.rb +6 -1
- data/spec/support/crud_tests/write/findOneAndUpdate-arrayFilters.yml +69 -0
- data/spec/support/crud_tests/write/updateMany-arrayFilters.yml +63 -0
- data/spec/support/crud_tests/write/updateOne-arrayFilters.yml +109 -0
- data/spec/support/sdam/rs/discover_arbiters.yml +1 -1
- data/spec/support/sdam/rs/discover_passives.yml +2 -2
- data/spec/support/sdam/rs/discover_primary.yml +1 -1
- data/spec/support/sdam/rs/discover_secondary.yml +1 -1
- data/spec/support/sdam/rs/discovery.yml +4 -4
- data/spec/support/sdam/rs/equal_electionids.yml +1 -0
- data/spec/support/sdam/rs/ghost_discovered.yml +1 -1
- data/spec/support/sdam/rs/hosts_differ_from_seeds.yml +1 -1
- data/spec/support/sdam/rs/ls_timeout.yml +88 -0
- data/spec/support/sdam/rs/member_reconfig.yml +2 -2
- data/spec/support/sdam/rs/member_standalone.yml +2 -2
- data/spec/support/sdam/rs/new_primary.yml +2 -2
- data/spec/support/sdam/rs/new_primary_new_electionid.yml +3 -0
- data/spec/support/sdam/rs/new_primary_new_setversion.yml +3 -0
- data/spec/support/sdam/rs/new_primary_wrong_set_name.yml +2 -2
- data/spec/support/sdam/rs/non_rs_member.yml +1 -1
- data/spec/support/sdam/rs/normalize_case.yml +1 -1
- data/spec/support/sdam/rs/null_election_id.yml +4 -0
- data/spec/support/sdam/rs/primary_becomes_standalone.yml +2 -2
- data/spec/support/sdam/rs/primary_changes_set_name.yml +2 -2
- data/spec/support/sdam/rs/primary_disconnect.yml +2 -2
- data/spec/support/sdam/rs/primary_disconnect_electionid.yml +5 -0
- data/spec/support/sdam/rs/primary_disconnect_setversion.yml +5 -0
- data/spec/support/sdam/rs/primary_hint_from_secondary_with_mismatched_me.yml +58 -0
- data/spec/support/sdam/rs/primary_reports_new_member.yml +4 -4
- data/spec/support/sdam/rs/primary_to_no_primary_mismatched_me.yml +2 -2
- data/spec/support/sdam/rs/primary_wrong_set_name.yml +1 -1
- data/spec/support/sdam/rs/response_from_removed.yml +2 -2
- data/spec/support/sdam/rs/rsother_discovered.yml +1 -1
- data/spec/support/sdam/rs/sec_not_auth.yml +1 -1
- data/spec/support/sdam/rs/secondary_wrong_set_name.yml +1 -1
- data/spec/support/sdam/rs/secondary_wrong_set_name_with_primary.yml +2 -2
- data/spec/support/sdam/rs/setversion_without_electionid.yml +2 -0
- data/spec/support/sdam/rs/stepdown_change_set_name.yml +2 -2
- data/spec/support/sdam/rs/unexpected_mongos.yml +1 -1
- data/spec/support/sdam/rs/use_setversion_without_electionid.yml +3 -0
- data/spec/support/sdam/rs/wrong_set_name.yml +1 -1
- data/spec/support/sdam/sharded/ls_timeout_mongos.yml +97 -0
- data/spec/support/sdam/sharded/mongos_disconnect.yml +3 -3
- data/spec/support/sdam/sharded/multiple_mongoses.yml +1 -1
- data/spec/support/sdam/sharded/non_mongos_removed.yml +1 -1
- data/spec/support/sdam/sharded/normalize_uri_case.yml +1 -1
- data/spec/support/sdam/single/direct_connection_external_ip.yml +1 -1
- data/spec/support/sdam/single/direct_connection_mongos.yml +1 -1
- data/spec/support/sdam/single/direct_connection_rsarbiter.yml +1 -1
- data/spec/support/sdam/single/direct_connection_rsprimary.yml +1 -1
- data/spec/support/sdam/single/direct_connection_rssecondary.yml +1 -1
- data/spec/support/sdam/single/direct_connection_slave.yml +1 -1
- data/spec/support/sdam/single/direct_connection_standalone.yml +1 -1
- data/spec/support/sdam/single/ls_timeout_standalone.yml +35 -0
- data/spec/support/sdam/single/not_ok_response.yml +1 -1
- data/spec/support/sdam/single/standalone_removed.yml +1 -1
- data/spec/support/sdam/single/unavailable_seed.yml +1 -1
- data/spec/support/server_discovery_and_monitoring.rb +4 -0
- data/spec/support/shared/session.rb +236 -0
- metadata +53 -15
- metadata.gz.sig +0 -0
@@ -50,7 +50,7 @@ module Mongo
|
|
50
50
|
def_delegators :view, :collection, :read, :cluster
|
51
51
|
|
52
52
|
# Delegate necessary operations to the collection.
|
53
|
-
def_delegators :collection, :database
|
53
|
+
def_delegators :collection, :database, :client
|
54
54
|
|
55
55
|
# Iterate through documents returned by the map/reduce.
|
56
56
|
#
|
@@ -66,10 +66,10 @@ module Mongo
|
|
66
66
|
# @yieldparam [ Hash ] Each matching document.
|
67
67
|
def each
|
68
68
|
@cursor = nil
|
69
|
-
|
70
|
-
|
71
|
-
result = send_initial_query(server)
|
72
|
-
@cursor = Cursor.new(view, result, server)
|
69
|
+
session = client.send(:get_session, view.options)
|
70
|
+
write_with_retry(session, Proc.new { server_selector.select_server(cluster, false) }) do |server|
|
71
|
+
result = send_initial_query(server, session)
|
72
|
+
@cursor = Cursor.new(view, result, server, session: session)
|
73
73
|
end
|
74
74
|
@cursor.each do |doc|
|
75
75
|
yield doc
|
@@ -182,20 +182,24 @@ module Mongo
|
|
182
182
|
|
183
183
|
private
|
184
184
|
|
185
|
+
def server_selector
|
186
|
+
@view.send(:server_selector)
|
187
|
+
end
|
188
|
+
|
185
189
|
def inline?
|
186
190
|
out.nil? || out == { inline: 1 } || out == { INLINE => 1 }
|
187
191
|
end
|
188
192
|
|
189
|
-
def map_reduce_spec
|
190
|
-
Builder::MapReduce.new(map, reduce, view, options).specification
|
193
|
+
def map_reduce_spec(session)
|
194
|
+
Builder::MapReduce.new(map, reduce, view, options.merge(session: session)).specification
|
191
195
|
end
|
192
196
|
|
193
197
|
def new(options)
|
194
198
|
MapReduce.new(view, map, reduce, options)
|
195
199
|
end
|
196
200
|
|
197
|
-
def initial_query_op
|
198
|
-
Operation::Commands::MapReduce.new(map_reduce_spec)
|
201
|
+
def initial_query_op(session)
|
202
|
+
Operation::Commands::MapReduce.new(map_reduce_spec(session))
|
199
203
|
end
|
200
204
|
|
201
205
|
def valid_server?(server)
|
@@ -206,34 +210,34 @@ module Mongo
|
|
206
210
|
out.respond_to?(:keys) && out.keys.first.to_s.downcase == INLINE
|
207
211
|
end
|
208
212
|
|
209
|
-
def send_initial_query(server)
|
213
|
+
def send_initial_query(server, session)
|
210
214
|
unless valid_server?(server)
|
211
215
|
log_warn(REROUTE)
|
212
216
|
server = cluster.next_primary(false)
|
213
217
|
end
|
214
218
|
validate_collation!(server)
|
215
|
-
result = initial_query_op.execute(server)
|
216
|
-
inline? ? result : send_fetch_query(server)
|
219
|
+
result = initial_query_op(session).execute(server)
|
220
|
+
inline? ? result : send_fetch_query(server, session)
|
217
221
|
end
|
218
222
|
|
219
223
|
def fetch_query_spec
|
220
224
|
Builder::MapReduce.new(map, reduce, view, options).query_specification
|
221
225
|
end
|
222
226
|
|
223
|
-
def find_command_spec
|
224
|
-
Builder::MapReduce.new(map, reduce, view, options).command_specification
|
227
|
+
def find_command_spec(session)
|
228
|
+
Builder::MapReduce.new(map, reduce, view, options.merge(session: session)).command_specification
|
225
229
|
end
|
226
230
|
|
227
|
-
def fetch_query_op(server)
|
231
|
+
def fetch_query_op(server, session)
|
228
232
|
if server.features.find_command_enabled?
|
229
|
-
Operation::Commands::Find.new(find_command_spec)
|
233
|
+
Operation::Commands::Find.new(find_command_spec(session))
|
230
234
|
else
|
231
235
|
Operation::Read::Query.new(fetch_query_spec)
|
232
236
|
end
|
233
237
|
end
|
234
238
|
|
235
|
-
def send_fetch_query(server)
|
236
|
-
fetch_query_op(server).execute(server)
|
239
|
+
def send_fetch_query(server, session)
|
240
|
+
fetch_query_op(server, session).execute(server)
|
237
241
|
end
|
238
242
|
|
239
243
|
def validate_collation!(server)
|
@@ -133,20 +133,24 @@ module Mongo
|
|
133
133
|
cmd[:limit] = opts[:limit] if opts[:limit]
|
134
134
|
cmd[:maxTimeMS] = opts[:max_time_ms] if opts[:max_time_ms]
|
135
135
|
cmd[:readConcern] = collection.read_concern if collection.read_concern
|
136
|
-
|
136
|
+
read_pref = opts[:read] || read_preference
|
137
|
+
selector = ServerSelector.get(read_pref || server_selector)
|
137
138
|
read_with_retry do
|
138
|
-
server =
|
139
|
+
server = selector.select_server(cluster, false)
|
139
140
|
apply_collation!(cmd, server, opts)
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
141
|
+
with_session do |session|
|
142
|
+
Operation::Commands::Command.new({
|
143
|
+
:selector => cmd,
|
144
|
+
:db_name => database.name,
|
145
|
+
:options => {:limit => -1},
|
146
|
+
:read => read_pref,
|
147
|
+
:session => session
|
148
|
+
}).execute(server)
|
149
|
+
end.n.to_i
|
147
150
|
end
|
148
151
|
end
|
149
152
|
|
153
|
+
|
150
154
|
# Get a list of distinct values for a specific field.
|
151
155
|
#
|
152
156
|
# @example Get the distinct values.
|
@@ -169,17 +173,20 @@ module Mongo
|
|
169
173
|
:query => filter }
|
170
174
|
cmd[:maxTimeMS] = opts[:max_time_ms] if opts[:max_time_ms]
|
171
175
|
cmd[:readConcern] = collection.read_concern if collection.read_concern
|
172
|
-
|
176
|
+
read_pref = opts[:read] || read_preference
|
177
|
+
selector = ServerSelector.get(read_pref || server_selector)
|
173
178
|
read_with_retry do
|
174
|
-
server =
|
179
|
+
server = selector.select_server(cluster, false)
|
175
180
|
apply_collation!(cmd, server, opts)
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
181
|
+
with_session do |session|
|
182
|
+
Operation::Commands::Command.new({
|
183
|
+
:selector => cmd,
|
184
|
+
:db_name => database.name,
|
185
|
+
:options => {:limit => -1},
|
186
|
+
:read => read_pref,
|
187
|
+
:session => session
|
188
|
+
}).execute(server)
|
189
|
+
end.first['values']
|
183
190
|
end
|
184
191
|
end
|
185
192
|
|
@@ -313,9 +320,8 @@ module Mongo
|
|
313
320
|
#
|
314
321
|
# @since 2.0.0
|
315
322
|
def read(value = nil)
|
316
|
-
return
|
317
|
-
|
318
|
-
configure(:read, selector)
|
323
|
+
return read_preference if value.nil?
|
324
|
+
configure(:read, value)
|
319
325
|
end
|
320
326
|
|
321
327
|
# Set whether to return only the indexed field or fields.
|
@@ -457,33 +463,41 @@ module Mongo
|
|
457
463
|
configure(:collation, doc)
|
458
464
|
end
|
459
465
|
|
460
|
-
def
|
461
|
-
options[:read] || collection.read_preference
|
466
|
+
def read_preference
|
467
|
+
@read_preference ||= (options[:read] || collection.read_preference)
|
468
|
+
end
|
469
|
+
|
470
|
+
def server_selector
|
471
|
+
@server_selector ||= ServerSelector.get(read_preference || collection.server_selector)
|
462
472
|
end
|
463
473
|
|
464
474
|
def parallel_scan(cursor_count, options = {})
|
465
|
-
|
475
|
+
session = client.send(:get_session, @options)
|
476
|
+
server = server_selector.select_server(cluster, false)
|
466
477
|
cmd = Operation::Commands::ParallelScan.new({
|
467
478
|
:coll_name => collection.name,
|
468
479
|
:db_name => database.name,
|
469
480
|
:cursor_count => cursor_count,
|
470
|
-
:read_concern => collection.read_concern
|
481
|
+
:read_concern => collection.read_concern,
|
482
|
+
:session => session
|
471
483
|
}.merge!(options))
|
472
484
|
cmd.execute(server).cursor_ids.map do |cursor_id|
|
473
485
|
result = if server.features.find_command_enabled?
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
486
|
+
Operation::Commands::GetMore.new({
|
487
|
+
:selector => {:getMore => cursor_id,
|
488
|
+
:collection => collection.name},
|
489
|
+
:db_name => database.name,
|
490
|
+
:session => session
|
491
|
+
}).execute(server)
|
492
|
+
else
|
493
|
+
Operation::Read::GetMore.new({
|
494
|
+
:to_return => 0,
|
495
|
+
:cursor_id => cursor_id,
|
496
|
+
:db_name => database.name,
|
497
|
+
:coll_name => collection.name
|
498
|
+
}).execute(server)
|
485
499
|
end
|
486
|
-
Cursor.new(self, result, server)
|
500
|
+
Cursor.new(self, result, server, session: session)
|
487
501
|
end
|
488
502
|
end
|
489
503
|
|
@@ -21,6 +21,11 @@ module Mongo
|
|
21
21
|
# @since 2.0.0
|
22
22
|
module Writable
|
23
23
|
|
24
|
+
# The array filters field constant.
|
25
|
+
#
|
26
|
+
# @since 2.5.0
|
27
|
+
ARRAY_FILTERS = 'array_filters'.freeze
|
28
|
+
|
24
29
|
# Finds a single document in the database via findAndModify and deletes
|
25
30
|
# it, returning the original document.
|
26
31
|
#
|
@@ -41,15 +46,16 @@ module Mongo
|
|
41
46
|
cmd[:maxTimeMS] = max_time_ms if max_time_ms
|
42
47
|
cmd[:writeConcern] = write_concern.options if write_concern
|
43
48
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
49
|
+
with_session do |session|
|
50
|
+
write_with_retry(session, Proc.new { next_primary }) do |server|
|
51
|
+
apply_collation!(cmd, server, opts)
|
52
|
+
Operation::Commands::Command.new({
|
53
|
+
:selector => cmd,
|
54
|
+
:db_name => database.name,
|
55
|
+
:session => session
|
56
|
+
}).execute(server)
|
57
|
+
end
|
58
|
+
end.first['value']
|
53
59
|
end
|
54
60
|
|
55
61
|
# Finds a single document and replaces it.
|
@@ -67,7 +73,7 @@ module Mongo
|
|
67
73
|
# @option opts [ true, false ] :upsert Whether to upsert if the document doesn't exist.
|
68
74
|
# @option opts [ true, false ] :bypass_document_validation Whether or
|
69
75
|
# not to skip document level validation.
|
70
|
-
# @option
|
76
|
+
# @option opts [ Hash ] :write_concern The write concern options.
|
71
77
|
# Defaults to the collection's write concern.
|
72
78
|
# @option opts [ Hash ] :collation The collation to use.
|
73
79
|
#
|
@@ -93,6 +99,8 @@ module Mongo
|
|
93
99
|
# @option opts [ Hash ] :write_concern The write concern options.
|
94
100
|
# Defaults to the collection's write concern.
|
95
101
|
# @option opts [ Hash ] :collation The collation to use.
|
102
|
+
# @options opts [ Array ] :array_filters A set of filters specifying to which array elements
|
103
|
+
# an update should apply.
|
96
104
|
#
|
97
105
|
# @return [ BSON::Document ] The document.
|
98
106
|
#
|
@@ -108,15 +116,17 @@ module Mongo
|
|
108
116
|
cmd[:bypassDocumentValidation] = !!opts[:bypass_document_validation]
|
109
117
|
cmd[:writeConcern] = write_concern.options if write_concern
|
110
118
|
|
111
|
-
value =
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
119
|
+
value = with_session do |session|
|
120
|
+
write_with_retry(session, Proc.new { next_primary }) do |server|
|
121
|
+
apply_collation!(cmd, server, opts)
|
122
|
+
apply_array_filters!(cmd, server, opts)
|
123
|
+
Operation::Commands::Command.new(
|
124
|
+
:selector => cmd,
|
125
|
+
:db_name => database.name,
|
126
|
+
:session => session
|
127
|
+
).execute(server)
|
128
|
+
end
|
129
|
+
end.first['value']
|
120
130
|
value unless value.nil? || value.empty?
|
121
131
|
end
|
122
132
|
|
@@ -182,6 +192,8 @@ module Mongo
|
|
182
192
|
# @option opts [ true, false ] :upsert Whether to upsert if the
|
183
193
|
# document doesn't exist.
|
184
194
|
# @option opts [ Hash ] :collation The collation to use.
|
195
|
+
# @option opts [ Array ] :array_filters A set of filters specifying to which array elements
|
196
|
+
# an update should apply.
|
185
197
|
#
|
186
198
|
# @return [ Result ] The response from the database.
|
187
199
|
#
|
@@ -201,6 +213,8 @@ module Mongo
|
|
201
213
|
# @option opts [ true, false ] :upsert Whether to upsert if the
|
202
214
|
# document doesn't exist.
|
203
215
|
# @option opts [ Hash ] :collation The collation to use.
|
216
|
+
# @option opts [ Array ] :array_filters A set of filters specifying to which array elements
|
217
|
+
# an update should apply.
|
204
218
|
#
|
205
219
|
# @return [ Result ] The response from the database.
|
206
220
|
#
|
@@ -213,16 +227,18 @@ module Mongo
|
|
213
227
|
|
214
228
|
def remove(value, opts = {})
|
215
229
|
delete_doc = { Operation::Q => filter, Operation::LIMIT => value }
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
230
|
+
|
231
|
+
with_session do |session|
|
232
|
+
write_with_retry(session, Proc.new { next_primary }) do |server|
|
233
|
+
apply_collation!(delete_doc, server, opts)
|
234
|
+
Operation::Write::Delete.new(
|
235
|
+
:delete => delete_doc,
|
236
|
+
:db_name => collection.database.name,
|
237
|
+
:coll_name => collection.name,
|
238
|
+
:write_concern => collection.write_concern,
|
239
|
+
:session => session
|
240
|
+
).execute(server)
|
241
|
+
end
|
226
242
|
end
|
227
243
|
end
|
228
244
|
|
@@ -231,17 +247,33 @@ module Mongo
|
|
231
247
|
Operation::U => spec,
|
232
248
|
Operation::MULTI => multi,
|
233
249
|
Operation::UPSERT => !!opts[:upsert] }
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
250
|
+
|
251
|
+
with_session do |session|
|
252
|
+
write_with_retry(session, Proc.new { next_primary }) do |server|
|
253
|
+
apply_collation!(update_doc, server, opts)
|
254
|
+
apply_array_filters!(update_doc, server, opts)
|
255
|
+
Operation::Write::Update.new(
|
256
|
+
:update => update_doc,
|
257
|
+
:db_name => collection.database.name,
|
258
|
+
:coll_name => collection.name,
|
259
|
+
:write_concern => collection.write_concern,
|
260
|
+
:bypass_document_validation => !!opts[:bypass_document_validation],
|
261
|
+
:session => session
|
262
|
+
).execute(server)
|
263
|
+
end
|
264
|
+
end
|
265
|
+
end
|
266
|
+
|
267
|
+
def apply_array_filters!(doc, server, opts = {})
|
268
|
+
if filters = opts[:array_filters] || opts[ARRAY_FILTERS]
|
269
|
+
validate_array_filters!(server, filters)
|
270
|
+
doc[:arrayFilters] = filters
|
271
|
+
end
|
272
|
+
end
|
273
|
+
|
274
|
+
def validate_array_filters!(server, filters)
|
275
|
+
if filters && !server.features.array_filters_enabled?
|
276
|
+
raise Error::UnsupportedArrayFilters.new
|
245
277
|
end
|
246
278
|
end
|
247
279
|
end
|
data/lib/mongo/cursor.rb
CHANGED
@@ -35,7 +35,7 @@ module Mongo
|
|
35
35
|
include Enumerable
|
36
36
|
include Retryable
|
37
37
|
|
38
|
-
def_delegators :@view, :collection
|
38
|
+
def_delegators :@view, :collection
|
39
39
|
def_delegators :collection, :client, :database
|
40
40
|
def_delegators :@server, :cluster
|
41
41
|
|
@@ -50,15 +50,21 @@ module Mongo
|
|
50
50
|
# @param [ CollectionView ] view The +CollectionView+ defining the query.
|
51
51
|
# @param [ Operation::Result ] result The result of the first execution.
|
52
52
|
# @param [ Server ] server The server this cursor is locked to.
|
53
|
+
# @param [ Hash ] options The cursor options.
|
54
|
+
#
|
55
|
+
# @option options [ true, false ] :disable_retry Whether to disable retrying on
|
56
|
+
# error when sending getmores.
|
53
57
|
#
|
54
58
|
# @since 2.0.0
|
55
|
-
def initialize(view, result, server)
|
59
|
+
def initialize(view, result, server, options = {})
|
56
60
|
@view = view
|
57
61
|
@server = server
|
58
62
|
@initial_result = result
|
59
63
|
@remaining = limit if limited?
|
60
64
|
@cursor_id = result.cursor_id
|
61
65
|
@coll_name = nil
|
66
|
+
@options = options
|
67
|
+
@session = @options[:session]
|
62
68
|
register
|
63
69
|
ObjectSpace.define_finalizer(self, self.class.finalize(result.cursor_id,
|
64
70
|
cluster,
|
@@ -185,14 +191,18 @@ module Mongo
|
|
185
191
|
end
|
186
192
|
|
187
193
|
def get_more
|
188
|
-
|
194
|
+
if @options[:disable_retry]
|
189
195
|
process(get_more_operation.execute(@server))
|
196
|
+
else
|
197
|
+
read_with_retry do
|
198
|
+
process(get_more_operation.execute(@server))
|
199
|
+
end
|
190
200
|
end
|
191
201
|
end
|
192
202
|
|
193
203
|
def get_more_operation
|
194
204
|
if @server.features.find_command_enabled?
|
195
|
-
Operation::Commands::GetMore.new(Builder::GetMoreCommand.new(self).specification)
|
205
|
+
Operation::Commands::GetMore.new(Builder::GetMoreCommand.new(self, @session).specification)
|
196
206
|
else
|
197
207
|
Operation::Read::GetMore.new(Builder::OpGetMore.new(self).specification)
|
198
208
|
end
|
@@ -203,6 +213,13 @@ module Mongo
|
|
203
213
|
read_with_one_retry do
|
204
214
|
kill_cursors_operation.execute(@server)
|
205
215
|
end
|
216
|
+
ensure
|
217
|
+
end_session
|
218
|
+
@cursor_id = 0
|
219
|
+
end
|
220
|
+
|
221
|
+
def end_session
|
222
|
+
@session.end_implicit_session if @session
|
206
223
|
end
|
207
224
|
|
208
225
|
def kill_cursors_operation
|
@@ -241,6 +258,10 @@ module Mongo
|
|
241
258
|
limited? && batch_size >= @remaining
|
242
259
|
end
|
243
260
|
|
261
|
+
def limit
|
262
|
+
@view.send(:limit)
|
263
|
+
end
|
264
|
+
|
244
265
|
def register
|
245
266
|
cluster.register_cursor(@cursor_id)
|
246
267
|
end
|