Fixed $hint and $explain support.

This commit is contained in:
Jim Menard 2009-01-14 10:42:56 -05:00
parent b82dd30579
commit fce980fc47
3 changed files with 43 additions and 30 deletions

View File

@ -125,13 +125,15 @@ module XGen
# Returns an explain plan record.
def explain
sel = OrderedHash.new
sel['query'] = @query.selector
sel['$explain'] = true
c = Cursor.new(@db, @collection, Query.new(sel))
e = c.next_object
old_val = @query.explain
@query.explain = true
c = Cursor.new(@db, @collection, @query)
explanation = c.next_object
c.close
e
@query.explain = old_val
explanation
end
# Close the cursor.
@ -210,18 +212,11 @@ module XGen
# Run query first time we request an object from the wire
unless @query_run
hints = @hint_fields || @collection.hint_fields
query = if hints
h = {}
hints.each { |field| h[field] = 1 }
sel = OrderedHash.new
sel['query'] = @query.selector
sel['$hint'] = h
Query.new(sel)
else
@query
end
@db.send_query_message(QueryMessage.new(@db.name, @collection.name, query))
old_hints = @query.hint_fields
@query.hint_fields = hints
@db.send_query_message(QueryMessage.new(@db.name, @collection.name, @query))
@query_run = true
@query.hint_fields = old_hints
read_all
end
end

View File

@ -18,21 +18,31 @@ module XGen
write_int(query.number_to_skip)
write_int(query.number_to_return)
sel = query.selector
if query.order_by && query.order_by.length > 0
if query.contains_special_fields
sel = OrderedHash.new
sel['query'] = query.selector
sel['orderby'] = case query.order_by
when String
{query.order_by => 1}
when Array
h = OrderedHash.new
query.order_by.each { |ob| h[ob] = 1 }
h
when Hash # Should be an ordered hash, but this message doesn't care
query.order_by
else
raise "illegal order_by: is a #{query.order_by.class.name}, must be String, Array, Hash, or OrderedHash"
end
if query.order_by && query.order_by.length > 0
sel['orderby'] = case query.order_by
when String
{query.order_by => 1}
when Array
h = OrderedHash.new
query.order_by.each { |ob| h[ob] = 1 }
h
when Hash # Should be an ordered hash, but this message doesn't care
query.order_by
else
raise "illegal order_by: is a #{query.order_by.class.name}, must be String, Array, Hash, or OrderedHash"
end
end
if query.hint_fields && query.hint_fields.length > 0
hints = OrderedHash.new
query.hint_fields.each { |hf| hints[hf] = 1 }
sel['$hint'] = hints
end
if query.explain
sel['$explain'] = true
end
end
write_doc(sel)

View File

@ -27,6 +27,10 @@ module XGen
class Query
attr_accessor :number_to_skip, :number_to_return, :order_by
# If true, $explain will be set in QueryMessage that uses this query.
attr_accessor :explain
# Either +nil+ or an array of hint field names.
attr_accessor :hint_fields
attr_reader :selector # writer defined below
# sel :: A hash describing the query. See the Mongo docs for details.
@ -97,6 +101,10 @@ module XGen
nil
end
end
def contains_special_fields
(@order_by != nil && @order_by.length > 0) || @explain || @hint_fields
end
end
end
end