Class: Mongo::Cursor Private
- Inherits:
-
Object
- Object
- Mongo::Cursor
- Extended by:
- Forwardable
- Includes:
- Enumerable, Retryable
- Defined in:
- lib/mongo/cursor.rb,
lib/mongo/cursor/builder/op_get_more.rb,
lib/mongo/cursor/builder/op_kill_cursors.rb,
lib/mongo/cursor/builder/get_more_command.rb,
lib/mongo/cursor/builder/kill_cursors_command.rb
Overview
This class is part of a private API. You should avoid using this class if possible, as it may be removed or be changed in the future.
Client-side representation of an iterator over a query result set on the server.
Cursor objects are not directly exposed to application code. Rather, Collection::View exposes the Enumerable interface to the applications, and the enumerator is backed by a Cursor instance.
Defined Under Namespace
Modules: Builder
Instance Attribute Summary collapse
-
#resume_token ⇒ BSON::Document | nil
readonly
private
The resume token tracked by the cursor for change stream resuming.
- #server ⇒ Object readonly private
-
#view ⇒ Collection::View
readonly
private
View The collection view.
Class Method Summary collapse
-
.finalize(cursor_id, cluster, op_spec, server, session) ⇒ Proc
private
Finalize the cursor for garbage collection.
Instance Method Summary collapse
-
#batch_size ⇒ Integer
private
Get the batch size.
-
#close ⇒ nil
private
Closes this cursor, freeing any associated resources on the client and the server.
-
#closed? ⇒ true, false
private
Is the cursor closed?.
-
#collection_name ⇒ String
private
Get the parsed collection name.
-
#each ⇒ Enumerator
private
Iterate through documents returned from the query.
-
#get_more ⇒ Array<BSON::Document>
private
Execute a getMore command and return the batch of documents obtained from the server.
-
#id ⇒ Integer
private
Get the cursor id.
-
#initialize(view, result, server, options = {}) ⇒ Cursor
constructor
private
Creates a
Cursorobject. -
#inspect ⇒ String
private
Get a human-readable string representation of
Cursor. -
#to_return ⇒ Integer
private
Get the number of documents to return.
-
#try_next ⇒ BSON::Document | nil
private
Return one document from the query, if one is available.
Methods included from Retryable
#legacy_write_with_retry, #nro_write_with_retry, #read_with_one_retry, #read_with_retry, #read_with_retry_cursor, #write_with_retry
Constructor Details
#initialize(view, result, server, options = {}) ⇒ Cursor
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Creates a Cursor object.
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
# File 'lib/mongo/cursor.rb', line 68 def initialize(view, result, server, = {}) @view = view @server = server @initial_result = result @remaining = limit if limited? @cursor_id = result.cursor_id if @cursor_id.nil? raise ArgumentError, 'Cursor id must be present in the result' end @coll_name = nil = @session = [:session] unless closed? register ObjectSpace.define_finalizer(self, self.class.finalize(@cursor_id, cluster, kill_cursors_op_spec, server, @session)) end end |
Instance Attribute Details
#resume_token ⇒ BSON::Document | nil (readonly)
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
The resume token tracked by the cursor for change stream resuming
49 50 51 |
# File 'lib/mongo/cursor.rb', line 49 def resume_token @resume_token end |
#server ⇒ Object (readonly)
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
91 92 93 |
# File 'lib/mongo/cursor.rb', line 91 def server @server end |
#view ⇒ Collection::View (readonly)
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Returns view The collection view.
43 44 45 |
# File 'lib/mongo/cursor.rb', line 43 def view @view end |
Class Method Details
.finalize(cursor_id, cluster, op_spec, server, session) ⇒ Proc
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Finalize the cursor for garbage collection. Schedules this cursor to be included in a killCursors operation executed by the Cluster’s CursorReaper.
107 108 109 110 111 112 |
# File 'lib/mongo/cursor.rb', line 107 def self.finalize(cursor_id, cluster, op_spec, server, session) proc do cluster.schedule_kill_cursor(cursor_id, op_spec, server) session.end_session if session && session.implicit? end end |
Instance Method Details
#batch_size ⇒ Integer
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Get the batch size.
244 245 246 |
# File 'lib/mongo/cursor.rb', line 244 def batch_size @view.batch_size && @view.batch_size > 0 ? @view.batch_size : limit end |
#close ⇒ nil
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Closes this cursor, freeing any associated resources on the client and the server.
267 268 269 270 271 272 273 274 275 276 277 278 279 |
# File 'lib/mongo/cursor.rb', line 267 def close return if closed? unregister read_with_one_retry do kill_cursors_operation.execute(@server, client: client) end nil ensure end_session @cursor_id = 0 end |
#closed? ⇒ true, false
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Is the cursor closed?
256 257 258 259 |
# File 'lib/mongo/cursor.rb', line 256 def closed? # @cursor_id should in principle never be nil @cursor_id.nil? || @cursor_id == 0 end |
#collection_name ⇒ String
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Get the parsed collection name.
289 290 291 |
# File 'lib/mongo/cursor.rb', line 289 def collection_name @coll_name || collection.name end |
#each ⇒ Enumerator
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Iterate through documents returned from the query.
A cursor may be iterated at most once. Incomplete iteration is also allowed. Attempting to iterate the cursor more than once raises InvalidCursorOperation.
140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 |
# File 'lib/mongo/cursor.rb', line 140 def each # If we already iterated past the first batch (i.e., called get_more # at least once), the cursor on the server side has advanced past # the first batch and restarting iteration from the beginning by # returning initial result would miss documents in the second batch # and subsequent batches up to wherever the cursor is. Detect this # condition and abort the iteration. # # In a future driver version, each would either continue from the # end of previous iteration or would always restart from the # beginning. if @get_more_called raise Error::InvalidCursorOperation, 'Cannot restart iteration of a cursor which issued a getMore' end # To maintain compatibility with pre-2.10 driver versions, reset # the documents array each time a new iteration is started. @documents = nil if block_given? # StopIteration raised by try_next ends this loop. loop do document = try_next yield document if document end self else documents = [] # StopIteration raised by try_next ends this loop. loop do document = try_next documents << document if document end documents end end |
#get_more ⇒ Array<BSON::Document>
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Execute a getMore command and return the batch of documents obtained from the server.
326 327 328 329 330 331 332 333 334 335 |
# File 'lib/mongo/cursor.rb', line 326 def get_more @get_more_called = true # Modern retryable reads specification prohibits retrying getMores. # Legacy retryable read logic used to retry getMores, but since # doing so may result in silent data loss, the driver no longer retries # getMore operations in any circumstance. # https://github.com/mongodb/specifications/blob/master/source/retryable-reads/retryable-reads.rst#qa process(get_more_operation.execute(@server, client: client)) end |
#id ⇒ Integer
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
A cursor id of 0 means the cursor was closed on the server.
Get the cursor id.
303 304 305 |
# File 'lib/mongo/cursor.rb', line 303 def id @cursor_id end |
#inspect ⇒ String
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Get a human-readable string representation of Cursor.
122 123 124 |
# File 'lib/mongo/cursor.rb', line 122 def inspect "#<Mongo::Cursor:0x#{object_id} @view=#{@view.inspect}>" end |
#to_return ⇒ Integer
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Get the number of documents to return. Used on 3.0 and lower server versions.
316 317 318 |
# File 'lib/mongo/cursor.rb', line 316 def to_return use_limit? ? @remaining : (batch_size || 0) end |
#try_next ⇒ BSON::Document | nil
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
This method is experimental and subject to change.
Return one document from the query, if one is available.
This method will wait up to max_await_time_ms milliseconds for changes from the server, and if no changes are received it will return nil. If there are no more documents to return from the server, or if we have exhausted the cursor, it will raise a StopIteration exception.
193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 |
# File 'lib/mongo/cursor.rb', line 193 def try_next if @documents.nil? # Since published versions of Mongoid have a copy of old driver cursor # code, our dup call in #process isn't invoked when Mongoid query # cache is active. Work around that by also calling dup here on # the result of #process which might come out of Mongoid's code. @documents = process(@initial_result).dup # the documents here can be an empty array, hence # we may end up issuing a getMore in the first try_next call end if @documents.empty? # On empty batches, we cache the batch resume token cache_batch_resume_token unless closed? if exhausted? close raise StopIteration end @documents = get_more else raise StopIteration end else # cursor is closed here # keep documents as an empty array end # If there is at least one document, cache its _id if @documents[0] cache_resume_token(@documents[0]) end # Cache the batch resume token if we are iterating # over the last document, or if the batch is empty if @documents.size <= 1 cache_batch_resume_token end return @documents.shift end |