Bug fixes:

- Make sure Query#fields returns a hash, not an array.
- Fix query limit by passing limit number to cursor and having it enforce the
  limit. (Database returns limit as first batch, but will continue to return
  data after the limit if requested.)
Improvements:
- Query#new can take a single field name instead of an array
- A few doc comment improvements here and there.
This commit is contained in:
Jim Menard 2009-01-07 09:46:30 -05:00
parent cecbebb1e9
commit 26b88efd3b
5 changed files with 41 additions and 12 deletions

View File

@ -54,6 +54,9 @@ type
= To Do = To Do
* Only update message sizes once, not after every write of a value. This will
require an explicit call to update_message_length in each message subclass.
* Tests for update and repsert. * Tests for update and repsert.
* Add a way to specify a collection of databases on startup (a simple array of * Add a way to specify a collection of databases on startup (a simple array of

View File

@ -29,14 +29,16 @@ module XGen
RESPONSE_HEADER_SIZE = 20 RESPONSE_HEADER_SIZE = 20
def initialize(db, collection) def initialize(db, collection, num_to_return=0)
@db, @collection = db, collection @db, @collection, @num_to_return = db, collection, num_to_return
@objects_returned = 0
@objects = [] @objects = []
@closed = false @closed = false
read_all read_all
end end
# Return +true+ if there are more records to retrieve. # Return +true+ if there are more records to retrieve. We do not check
# @num_to_return; #each is responsible for doing that.
def more? def more?
num_remaining > 0 num_remaining > 0
end end
@ -49,10 +51,14 @@ module XGen
o o
end end
# Iterate over each object, yielding it to the given block. # Iterate over each object, yielding it to the given block. At most
# @num_to_return records are returned (or all of them, if
# @num_to_return is 0).
def each def each
while more? num_returned = 0
while more? && (@num_to_return <= 0 || num_returned < @num_to_return)
yield next_object() yield next_object()
num_returned += 1
end end
end end

View File

@ -163,7 +163,7 @@ module XGen
def query(collection_name, query) def query(collection_name, query)
# TODO synchronize # TODO synchronize
send_to_db(QueryMessage.new(@name, collection_name, query)) send_to_db(QueryMessage.new(@name, collection_name, query))
return Cursor.new(self, collection_name) return Cursor.new(self, collection_name, query.number_to_return)
end end
# Remove the records that match +selector+ from +collection_name+. # Remove the records that match +selector+ from +collection_name+.

View File

@ -27,20 +27,21 @@ module XGen
class Query class Query
attr_accessor :number_to_skip, :number_to_return, :order_by attr_accessor :number_to_skip, :number_to_return, :order_by
attr_reader :selector, :fields # writers defined below attr_reader :selector # writer defined below
# sel :: A hash describing the query. See the Mongo docs for details. # sel :: A hash describing the query. See the Mongo docs for details.
# #
# return_fields :: If not +nil+, an array of field names. Only those # return_fields :: If not +nil+, a single field name or an array of
# fields will be returned. (Called :fields in calls # field names. Only those fields will be returned.
# to Collection#find.) # (Called :fields in calls to Collection#find.)
# #
# number_to_skip :: Number of records to skip before returning # number_to_skip :: Number of records to skip before returning
# records. (Called :offset in calls to # records. (Called :offset in calls to
# Collection#find.) # Collection#find.) Default is 0.
# #
# number_to_return :: Max number of records to return. (Called :limit # number_to_return :: Max number of records to return. (Called :limit
# in calls to Collection#find.) # in calls to Collection#find.) Default is 0 (all
# records).
# #
# order_by :: If not +nil+, specifies record sort order. May be either # order_by :: If not +nil+, specifies record sort order. May be either
# a hash or an array. If an array, it should be an array # a hash or an array. If an array, it should be an array
@ -77,6 +78,23 @@ module XGen
@fields = val @fields = val
@fields = nil if @fields && @fields.empty? @fields = nil if @fields && @fields.empty?
end end
def fields
case @fields
when String
{@fields => 1}
when Array
if @fields.length == 0
nil
else
h = {}
@fields.each { |field| h[field] = 1 }
h
end
else # nil, anything else
nil
end
end
end end
end end
end end

View File

@ -183,6 +183,8 @@ class DBAPITest < Test::Unit::TestCase
assert_equal 4, docs.size assert_equal 4, docs.size
docs = @coll.find({}).map{ |x| x } docs = @coll.find({}).map{ |x| x }
assert_equal 4, docs.size assert_equal 4, docs.size
docs = @coll.find({}, :limit => 99).map{ |x| x }
assert_equal 4, docs.size
end end
def test_close def test_close