add command option for Collection#group

This commit is contained in:
Mike Dirolf 2009-08-19 15:54:53 -04:00
parent c6969fcb4d
commit 040ba7c9c2
2 changed files with 30 additions and 2 deletions

View File

@ -302,12 +302,33 @@ module XGen
# #
# Returns an array of grouped items. # Returns an array of grouped items.
# #
# :keys :: list of fields to group by # :keys :: Array of fields to group by
# :condition :: specification of rows to be considered (as a 'find' # :condition :: specification of rows to be considered (as a 'find'
# query specification) # query specification)
# :initial :: initial value of the aggregation counter object # :initial :: initial value of the aggregation counter object
# :reduce :: aggregation function as a JavaScript string # :reduce :: aggregation function as a JavaScript string
def group(keys, condition, initial, reduce) # :command :: if true, run the group as a command instead of in an
# eval - it is likely that this option will eventually be
# deprecated and all groups will be run as commands
def group(keys, condition, initial, reduce, command=false)
if command
hash = {}
keys.each do |k|
hash[k] = 1
end
result = @db.db_command({"group" =>
{
"ns" => @name,
"$reduce" => Code.new(reduce),
"key" => hash,
"cond" => condition,
"initial" => initial}})
if result["ok"] == 1
return result["retval"]
else
raise OperationFailure, "group command failed: #{result['errmsg']}"
end
end
group_function = <<EOS group_function = <<EOS
function () { function () {
var c = db[ns].find(condition); var c = db[ns].find(condition);

View File

@ -600,23 +600,30 @@ class DBAPITest < Test::Unit::TestCase
test = @@db.collection("test") test = @@db.collection("test")
assert_equal [], test.group([], {}, {"count" => 0}, "function (obj, prev) { prev.count++; }") assert_equal [], test.group([], {}, {"count" => 0}, "function (obj, prev) { prev.count++; }")
assert_equal [], test.group([], {}, {"count" => 0}, "function (obj, prev) { prev.count++; }", true)
test.insert("a" => 2) test.insert("a" => 2)
test.insert("b" => 5) test.insert("b" => 5)
test.insert("a" => 1) test.insert("a" => 1)
assert_equal 3, test.group([], {}, {"count" => 0}, "function (obj, prev) { prev.count++; }")[0]["count"] assert_equal 3, test.group([], {}, {"count" => 0}, "function (obj, prev) { prev.count++; }")[0]["count"]
assert_equal 3, test.group([], {}, {"count" => 0}, "function (obj, prev) { prev.count++; }", true)[0]["count"]
assert_equal 1, test.group([], {"a" => {"$gt" => 1}}, {"count" => 0}, "function (obj, prev) { prev.count++; }")[0]["count"] assert_equal 1, test.group([], {"a" => {"$gt" => 1}}, {"count" => 0}, "function (obj, prev) { prev.count++; }")[0]["count"]
assert_equal 1, test.group([], {"a" => {"$gt" => 1}}, {"count" => 0}, "function (obj, prev) { prev.count++; }", true)[0]["count"]
test.insert("a" => 2, "b" => 3) test.insert("a" => 2, "b" => 3)
expected = [{"a" => 2, "count" => 2}, expected = [{"a" => 2, "count" => 2},
{"a" => nil, "count" => 1}, {"a" => nil, "count" => 1},
{"a" => 1, "count" => 1}] {"a" => 1, "count" => 1}]
assert_equal expected, test.group(["a"], {}, {"count" => 0}, "function (obj, prev) { prev.count++; }") assert_equal expected, test.group(["a"], {}, {"count" => 0}, "function (obj, prev) { prev.count++; }")
assert_equal expected, test.group(["a"], {}, {"count" => 0}, "function (obj, prev) { prev.count++; }", true)
assert_raise OperationFailure do assert_raise OperationFailure do
test.group([], {}, {}, "5 ++ 5") test.group([], {}, {}, "5 ++ 5")
end end
assert_raise OperationFailure do
test.group([], {}, {}, "5 ++ 5", true)
end
end end
def test_deref def test_deref