add support for snapshot option to Collection#find

This commit is contained in:
Mike Dirolf 2009-08-11 11:42:34 -04:00
parent c9658f1044
commit 4963da9e89
4 changed files with 21 additions and 7 deletions

View File

@ -67,6 +67,11 @@ module XGen
# ascending, -1 == descending, or array of field names (all
# assumed to be sorted in ascending order).
# :hint :: See #hint. This option overrides the collection-wide value.
# :snapshot :: If true, snapshot mode will be used for this query.
# Snapshot mode assures no duplicates are returned, or
# objects missed, which were preset at both the start and
# end of the query's execution. For details see
# http://www.mongodb.org/display/DOCS/How+to+do+Snapshotting+in+the+Mongo+Database
def find(selector={}, options={})
fields = options.delete(:fields)
fields = nil if fields && fields.empty?
@ -74,13 +79,14 @@ module XGen
limit = options.delete(:limit) || 0
sort = options.delete(:sort)
hint = options.delete(:hint)
snapshot = options.delete(:snapshot)
if hint
hint = normalize_hint_fields(hint)
else
hint = @hint # assumed to be normalized already
end
raise RuntimeError, "Unknown options [#{options.inspect}]" unless options.empty?
@db.query(self, Query.new(selector, fields, offset, limit, sort, hint))
@db.query(self, Query.new(selector, fields, offset, limit, sort, hint, snapshot))
end
# Find the first record that matches +selector+. See #find.

View File

@ -62,7 +62,7 @@ module XGen
end
sel['$hint'] = query.hint if query.hint && query.hint.length > 0
sel['$explain'] = true if query.explain
sel['$snapshot'] = true if query.snapshot
end
write_doc(sel)
write_doc(query.fields) if query.fields

View File

@ -26,7 +26,7 @@ module XGen
# Mongo documentation for query details.
class Query
attr_accessor :number_to_skip, :number_to_return, :order_by
attr_accessor :number_to_skip, :number_to_return, :order_by, :snapshot
# If true, $explain will be set in QueryMessage that uses this query.
attr_accessor :explain
# Either +nil+ or a hash (preferably an OrderedHash).
@ -63,9 +63,9 @@ module XGen
# hint :: If not +nil+, specifies query hint fields. Must be either
# +nil+ or a hash (preferably an OrderedHash). See
# Collection#hint.
def initialize(sel={}, return_fields=nil, number_to_skip=0, number_to_return=0, order_by=nil, hint=nil)
@number_to_skip, @number_to_return, @order_by, @hint =
number_to_skip, number_to_return, order_by, hint
def initialize(sel={}, return_fields=nil, number_to_skip=0, number_to_return=0, order_by=nil, hint=nil, snapshot=nil)
@number_to_skip, @number_to_return, @order_by, @hint, @snapshot =
number_to_skip, number_to_return, order_by, hint, snapshot
@explain = nil
self.selector = sel
self.fields = return_fields
@ -111,7 +111,7 @@ module XGen
end
def contains_special_fields
(@order_by != nil && @order_by.length > 0) || @explain || @hint
(@order_by != nil && @order_by.length > 0) || @explain || @hint || @snapshot
end
end
end

View File

@ -781,6 +781,14 @@ class DBAPITest < Test::Unit::TestCase
assert_equal 0, b.count()
end
# doesn't really test functionality, just that the option is set correctly
def test_snapshot
@@db.collection("test").find({}, :snapshot => true).to_a
assert_raise RuntimeError do
@@db.collection("test").find({}, :snapshot => true, :sort => 'a').to_a
end
end
# TODO this test fails with error message "Undefed Before end of object"
# That is a database error. The undefined type may go away.