Class: Mongo::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, admin = false) ⇒ Cursor

Create a new cursor.

Should not be called directly by application developers.



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

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

Instance Attribute Details

#collectionObject (readonly)

Returns the value of attribute collection.



28
29
30
# File 'lib/mongo/cursor.rb', line 28

def collection
  @collection
end

#dbObject (readonly)

Returns the value of attribute db.



28
29
30
# File 'lib/mongo/cursor.rb', line 28

def db
  @db
end

#queryObject (readonly)

Returns the value of attribute query.



28
29
30
# File 'lib/mongo/cursor.rb', line 28

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.

Collection#find takes an optional block argument which can be used to ensure that your cursors get closed. See the documentation for Collection#find for details.



129
130
131
132
133
134
# File 'lib/mongo/cursor.rb', line 129

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

#closed?Boolean

Returns true if this cursor is closed, false otherwise.

Returns:

  • (Boolean)


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

def closed?; @closed; end

#countObject

Get the size of the results set for this query.

Returns the number of objects in the results set for this query. Does not take limit and skip into account. Raises OperationFailure on a database error.

Raises:



67
68
69
70
71
72
73
74
75
# File 'lib/mongo/cursor.rb', line 67

def count
  command = OrderedHash["count", @collection.name,
                        "query", @query.selector,
                        "fields", @query.fields()]
  response = @db.db_command(command)
  return response['n'].to_i if response['ok'] == 1
  return 0 if response['errmsg'] == "ns missing"
  raise OperationFailure, "Count failed: #{response['errmsg']}"
end

#eachObject

Iterate over each document in this cursor, yielding it to the given block.

Iterating over an entire cursor will close it.



81
82
83
84
85
86
87
# File 'lib/mongo/cursor.rb', line 81

def each
  num_returned = 0
  while more? && (@num_to_return <= 0 || num_returned < @num_to_return)
    yield next_object()
    num_returned += 1
  end
end

#explainObject

Returns an explain plan record for this cursor.



108
109
110
111
112
113
114
115
116
117
118
# File 'lib/mongo/cursor.rb', line 108

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

#next_objectObject

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



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/mongo/cursor.rb', line 43

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 documents in this cursor as an array of hashes.

Raises InvalidOperation if this cursor has already been used (including any previous calls to this method).

Use of this method is discouraged - iterating over a cursor is much more efficient in most cases.

Raises:



96
97
98
99
100
101
102
103
104
105
# File 'lib/mongo/cursor.rb', line 96

def to_a
  raise InvalidOperation, "can't call Cursor#to_a on a used cursor" if @query_run
  rows = []
  num_returned = 0
  while more? && (@num_to_return <= 0 || num_returned < @num_to_return)
    rows << next_object()
    num_returned += 1
  end
  rows
end