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 # ascending, -1 == descending, or array of field names (all
# assumed to be sorted in ascending order). # assumed to be sorted in ascending order).
# :hint :: See #hint. This option overrides the collection-wide value. # :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={}) def find(selector={}, options={})
fields = options.delete(:fields) fields = options.delete(:fields)
fields = nil if fields && fields.empty? fields = nil if fields && fields.empty?
@ -74,13 +79,14 @@ module XGen
limit = options.delete(:limit) || 0 limit = options.delete(:limit) || 0
sort = options.delete(:sort) sort = options.delete(:sort)
hint = options.delete(:hint) hint = options.delete(:hint)
snapshot = options.delete(:snapshot)
if hint if hint
hint = normalize_hint_fields(hint) hint = normalize_hint_fields(hint)
else else
hint = @hint # assumed to be normalized already hint = @hint # assumed to be normalized already
end end
raise RuntimeError, "Unknown options [#{options.inspect}]" unless options.empty? 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 end
# Find the first record that matches +selector+. See #find. # Find the first record that matches +selector+. See #find.

View File

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

View File

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

View File

@ -781,6 +781,14 @@ class DBAPITest < Test::Unit::TestCase
assert_equal 0, b.count() assert_equal 0, b.count()
end 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" # TODO this test fails with error message "Undefed Before end of object"
# That is a database error. The undefined type may go away. # That is a database error. The undefined type may go away.