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

View File

@ -18,9 +18,10 @@ module XGen
write_int(query.number_to_skip) write_int(query.number_to_skip)
write_int(query.number_to_return) write_int(query.number_to_return)
sel = query.selector sel = query.selector
if query.order_by && query.order_by.length > 0 if query.contains_special_fields
sel = OrderedHash.new sel = OrderedHash.new
sel['query'] = query.selector sel['query'] = query.selector
if query.order_by && query.order_by.length > 0
sel['orderby'] = case query.order_by sel['orderby'] = case query.order_by
when String when String
{query.order_by => 1} {query.order_by => 1}
@ -33,6 +34,15 @@ module XGen
else else
raise "illegal order_by: is a #{query.order_by.class.name}, must be String, Array, Hash, or OrderedHash" raise "illegal order_by: is a #{query.order_by.class.name}, must be String, Array, Hash, or OrderedHash"
end 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 end
write_doc(sel) write_doc(sel)

View File

@ -27,6 +27,10 @@ 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
# 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 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.
@ -97,6 +101,10 @@ module XGen
nil nil
end end
end end
def contains_special_fields
(@order_by != nil && @order_by.length > 0) || @explain || @hint_fields
end
end end
end end
end end