Class: XGen::Mongo::Driver::Cursor

Inherits:
Object
  • Object
show all
Includes:
Enumerable
Defined in:
lib/mongo/cursor.rb

Overview

A cursor over query results. Returned objects are hashes.

Constant Summary collapse

RESPONSE_HEADER_SIZE =
20

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(db, collection, query) ⇒ Cursor

Returns a new instance of Cursor.



34
35
36
37
38
39
40
41
42
# File 'lib/mongo/cursor.rb', line 34

def initialize(db, collection, query)
  @db, @collection, @query = db, collection, query
  @num_to_return = @query.number_to_return || 0
  @cache = []
  @closed = false
  @can_call_to_a = true
  @query_run = false
  @rows = nil
end

Instance Attribute Details

#collectionObject (readonly)

Returns the value of attribute collection.



32
33
34
# File 'lib/mongo/cursor.rb', line 32

def collection
  @collection
end

#dbObject (readonly)

Returns the value of attribute db.



32
33
34
# File 'lib/mongo/cursor.rb', line 32

def db
  @db
end

#queryObject (readonly)

Returns the value of attribute query.



32
33
34
# File 'lib/mongo/cursor.rb', line 32

def query
  @query
end

Instance Method Details

#closeObject

Close the cursor.

Note: if a cursor is read until exhausted (read until OP_QUERY or OP_GETMORE returns zero for the cursor id), there is no need to close it by calling this method.



141
142
143
144
145
146
# File 'lib/mongo/cursor.rb', line 141

def close
  @db.send_to_db(KillCursorsMessage.new(@cursor_id)) if @cursor_id
  @cache = []
  @cursor_id = 0
  @closed = true
end

#closed?Boolean

Returns:

  • (Boolean)


44
# File 'lib/mongo/cursor.rb', line 44

def closed?; @closed; end

#eachObject

Iterate over each object, yielding it to the given block. At most If #to_a has already been called then this method uses the array that we store internally. In that case, #each can be called multiple times because it re-uses that array.

You can call #each after calling #to_a (multiple times even, because it will use the internally-stored array), but you can’t call #to_a after calling #each unless you also called it before calling #each. If you try to do that, an error will be raised.



86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/mongo/cursor.rb', line 86

def each
  if @rows              # Already turned into an array
    @rows.each { |row| yield row }
  else
    num_returned = 0
    while more? && (@num_to_return <= 0 || num_returned < @num_to_return)
      yield next_object()
      num_returned += 1
    end
    @can_call_to_a = false
  end
end

#explainObject

Returns an explain plan record.



124
125
126
127
128
129
130
131
132
133
134
# File 'lib/mongo/cursor.rb', line 124

def explain
  old_val = @query.explain
  @query.explain = true

  c = Cursor.new(@db, @collection, @query)
  explanation = c.next_object
  c.close

  @query.explain = old_val
  explanation
end

#more?Boolean

Internal method, not for general use. Return true if there are more records to retrieve. We do not check @num_to_return; #each is responsible for doing that.

Returns:

  • (Boolean)


49
50
51
# File 'lib/mongo/cursor.rb', line 49

def more?
  num_remaining > 0
end

#next_objectObject

Return the next object or nil if there are no more. Raises an error if necessary.



55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/mongo/cursor.rb', line 55

def next_object
  refill_via_get_more if num_remaining == 0
  o = @cache.shift

  if o && o['$err']
    err = o['$err']

    # If the server has stopped being the master (e.g., it's one of a
    # pair but it has died or something like that) then we close that
    # connection. If the db has auto connect option and a pair of
    # servers, next request will re-open on master server.
    @db.close if err == "not master"

    raise err
  end

  o
end

#to_aObject

Return all of the rows (up to the num_to_return value specified in #new) as an array. Calling this multiple times will work fine; it always returns the same array.

Don’t use this if you’re expecting large amounts of data, of course. All of the returned rows are kept in an array stored in this object so it can be reused.

You can call #each after calling #to_a (multiple times even, because it will use the internally-stored array), but you can’t call #to_a after calling #each unless you also called it before calling #each. If you try to do that, an error will be raised.



111
112
113
114
115
116
117
118
119
120
121
# File 'lib/mongo/cursor.rb', line 111

def to_a
  return @rows if @rows
  raise "can't call Cursor#to_a after calling Cursor#each" unless @can_call_to_a
  @rows = []
  num_returned = 0
  while more? && (@num_to_return <= 0 || num_returned < @num_to_return)
    @rows << next_object()
    num_returned += 1
  end
  @rows
end