Merge branch 'master' of github.com:mongodb/mongo-ruby-driver
This commit is contained in:
commit
f9fb823c53
4
CREDITS
4
CREDITS
@ -47,11 +47,13 @@ Les Hill, leshill on github
|
||||
* OrderedHash#each returns self
|
||||
|
||||
Sean Cribbs, seancribbs on github
|
||||
* Modify standard_benchmark to allow profiling
|
||||
* Modified standard_benchmark to allow profiling
|
||||
* c ext for faster ObjectID creation
|
||||
|
||||
Sunny Hirai
|
||||
* Suggested hashcode fix for Mongo::ObjectID
|
||||
* Noted index ordering bug.
|
||||
* GridFS performance boost
|
||||
|
||||
Christos Trochalakis
|
||||
* Added map/reduce helper
|
||||
|
@ -1,26 +0,0 @@
|
||||
$LOAD_PATH[0,0] = File.join(File.dirname(__FILE__), '..', 'lib')
|
||||
require 'mongo'
|
||||
|
||||
db = Mongo::Connection.new({:left => ["localhost", 27017], :right => ["localhost", 27018]}, nil, :auto_reconnect => true).db("ruby_test")
|
||||
|
||||
db['test'].clear
|
||||
10.times do |i|
|
||||
db['test'].save("x" => i)
|
||||
end
|
||||
|
||||
while true do
|
||||
begin
|
||||
exit() if not db['test'].count() == 10
|
||||
|
||||
x = 0
|
||||
db['test'].find().each do |doc|
|
||||
x += doc['x']
|
||||
end
|
||||
exit() if not x == 45
|
||||
print "."
|
||||
STDOUT.flush
|
||||
sleep 1
|
||||
rescue
|
||||
sleep 1
|
||||
end
|
||||
end
|
@ -2,7 +2,7 @@
|
||||
require 'rubygems'
|
||||
require 'mongo'
|
||||
require 'mongo/gridfs'
|
||||
require 'benchmark'
|
||||
#require 'ruby-prof'
|
||||
|
||||
include Mongo
|
||||
include GridFS
|
||||
@ -15,10 +15,15 @@ length = sample_data.length
|
||||
mb = length / 1048576.0
|
||||
|
||||
t1 = Time.now
|
||||
#RubyProf.start
|
||||
GridStore.open(db, 'mongodb.pdf', 'w') do |f|
|
||||
f.write(sample_data)
|
||||
end
|
||||
#result = RubyProf.stop
|
||||
puts "Write: #{mb / (Time.now - t1)} mb/s"
|
||||
#printer = RubyProf::FlatPrinter.new(result)
|
||||
#printer.print(STDOUT, 0)
|
||||
|
||||
|
||||
t1 = Time.now
|
||||
GridStore.open(db, 'mongodb.pdf', 'r') do |f|
|
||||
|
@ -33,14 +33,14 @@ array = cursor.to_a
|
||||
cursor.each { |row| pp row }
|
||||
|
||||
# You can get the next object
|
||||
first_object = coll.find().next_object
|
||||
first_object = coll.find().next_document
|
||||
|
||||
# next_object returns nil if there are no more objects that match
|
||||
# next_document returns nil if there are no more objects that match
|
||||
cursor = coll.find()
|
||||
obj = cursor.next_object
|
||||
obj = cursor.next_document
|
||||
while obj
|
||||
pp obj
|
||||
obj = cursor.next_object
|
||||
obj = cursor.next_document
|
||||
end
|
||||
|
||||
# Destroy the collection
|
||||
|
@ -30,6 +30,6 @@ coll.insert('array' => [1, 2, 3],
|
||||
'null' => nil,
|
||||
'symbol' => :zildjian)
|
||||
|
||||
pp coll.find().next_object
|
||||
pp coll.find().next_document
|
||||
|
||||
coll.clear
|
||||
|
@ -459,6 +459,7 @@ static void write_doc(buffer_t buffer, VALUE hash, VALUE check_keys) {
|
||||
|
||||
// make sure that length doesn't exceed 4MB
|
||||
if (length > 4 * 1024 * 1024) {
|
||||
buffer_free(buffer);
|
||||
rb_raise(InvalidDocument, "Document too large: BSON documents are limited to 4MB.");
|
||||
return;
|
||||
}
|
||||
|
@ -59,8 +59,7 @@ module Mongo
|
||||
raise "Error with profile command: #{doc.inspect}" unless @db.ok?(doc)
|
||||
end
|
||||
|
||||
# Return an array contining current profiling information from the
|
||||
# database.
|
||||
# Returns an array containing current profiling information.
|
||||
def profiling_info
|
||||
Cursor.new(Collection.new(@db, DB::SYSTEM_PROFILE_COLLECTION), :selector => {}).to_a
|
||||
end
|
||||
|
@ -158,7 +158,7 @@ module Mongo
|
||||
else
|
||||
raise TypeError, "spec_or_object_id must be an instance of ObjectID or Hash, or nil"
|
||||
end
|
||||
find(spec, options.merge(:limit => -1)).next_object
|
||||
find(spec, options.merge(:limit => -1)).next_document
|
||||
end
|
||||
|
||||
# Save a document in this collection.
|
||||
@ -497,7 +497,7 @@ EOS
|
||||
# 'create' will be the collection name. For the other possible keys
|
||||
# and values, see DB#create_collection.
|
||||
def options
|
||||
@db.collections_info(@name).next_object()['options']
|
||||
@db.collections_info(@name).next_document['options']
|
||||
end
|
||||
|
||||
# Get the number of documents in this collection.
|
||||
@ -526,7 +526,7 @@ EOS
|
||||
|
||||
private
|
||||
|
||||
# Sends an Mongo::Constants::OP_INSERT message to the database.
|
||||
# Sends a Mongo::Constants::OP_INSERT message to the database.
|
||||
# Takes an array of +documents+, an optional +collection_name+, and a
|
||||
# +check_keys+ setting.
|
||||
def insert_documents(documents, collection_name=@name, check_keys=true, safe=false)
|
||||
|
@ -49,19 +49,17 @@ module Mongo
|
||||
@query_run = false
|
||||
end
|
||||
|
||||
# Return the next object or nil if there are no more. Raises an error
|
||||
# if necessary.
|
||||
def next_object
|
||||
# Return the next document or nil if there are no more.
|
||||
def next_document
|
||||
refill_via_get_more if num_remaining == 0
|
||||
o = @cache.shift
|
||||
doc = @cache.shift
|
||||
|
||||
if o && o['$err']
|
||||
err = o['$err']
|
||||
if doc && doc['$err']
|
||||
err = doc['$err']
|
||||
|
||||
# If the server has stopped being the master (e.g., it's one of a
|
||||
# pair but it has died or something like that) then we close that
|
||||
# connection. If the db has auto connect option and a pair of
|
||||
# servers, next request will re-open on master server.
|
||||
# connection. The next request will re-open on master server.
|
||||
if err == "not master"
|
||||
raise ConnectionFailure, err
|
||||
@connection.close
|
||||
@ -70,12 +68,17 @@ module Mongo
|
||||
raise OperationFailure, err
|
||||
end
|
||||
|
||||
o
|
||||
doc
|
||||
end
|
||||
|
||||
# Get the size of the results set for this query.
|
||||
def next_object
|
||||
warn "Cursor#next_object is deprecated; please use Cursor#next_document instead."
|
||||
next_document
|
||||
end
|
||||
|
||||
# Get the size of the result set for this query.
|
||||
#
|
||||
# Returns the number of objects in the results set for this query. Does
|
||||
# Returns the number of objects in the result set for this query. Does
|
||||
# not take limit and skip into account. Raises OperationFailure on a
|
||||
# database error.
|
||||
def count
|
||||
@ -88,17 +91,17 @@ module Mongo
|
||||
raise OperationFailure, "Count failed: #{response['errmsg']}"
|
||||
end
|
||||
|
||||
# Sort this cursor's result
|
||||
# Sort this cursor's results.
|
||||
#
|
||||
# Takes either a single key and a direction, or an array of [key,
|
||||
# direction] pairs. Directions should be specified as Mongo::ASCENDING
|
||||
# or Mongo::DESCENDING (or :ascending or :descending) (or :asc or :desc).
|
||||
# direction] pairs. Directions should be specified as Mongo::ASCENDING / Mongo::DESCENDING
|
||||
# (or :ascending / :descending, :asc / :desc).
|
||||
#
|
||||
# Raises InvalidOperation if this cursor has already been used. Raises
|
||||
# InvalidSortValueError if specified order is invalid.
|
||||
# InvalidSortValueError if the specified order is invalid.
|
||||
#
|
||||
# This method overrides any sort order specified in the Collection#find
|
||||
# method, and only the last sort applied has an effect
|
||||
# method, and only the last sort applied has an effect.
|
||||
def sort(key_or_list, direction=nil)
|
||||
check_modifiable
|
||||
|
||||
@ -151,15 +154,15 @@ module Mongo
|
||||
def each
|
||||
num_returned = 0
|
||||
while more? && (@limit <= 0 || num_returned < @limit)
|
||||
yield next_object()
|
||||
yield next_document
|
||||
num_returned += 1
|
||||
end
|
||||
end
|
||||
|
||||
# Return all of the documents in this cursor as an array of hashes.
|
||||
#
|
||||
# Raises InvalidOperation if this cursor has already been used (including
|
||||
# any previous calls to this method).
|
||||
# Raises InvalidOperation if this cursor has already been used or if
|
||||
# this methods has already been called on the cursor.
|
||||
#
|
||||
# Use of this method is discouraged - iterating over a cursor is much
|
||||
# more efficient in most cases.
|
||||
@ -168,22 +171,22 @@ module Mongo
|
||||
rows = []
|
||||
num_returned = 0
|
||||
while more? && (@limit <= 0 || num_returned < @limit)
|
||||
rows << next_object()
|
||||
rows << next_document
|
||||
num_returned += 1
|
||||
end
|
||||
rows
|
||||
end
|
||||
|
||||
# Returns an explain plan record for this cursor.
|
||||
# Returns an explain plan document for this cursor.
|
||||
def explain
|
||||
c = Cursor.new(@collection, query_options_hash.merge(:limit => -@limit.abs, :explain => true))
|
||||
explanation = c.next_object
|
||||
explanation = c.next_document
|
||||
c.close
|
||||
|
||||
explanation
|
||||
end
|
||||
|
||||
# Close the cursor.
|
||||
# Closes the cursor.
|
||||
#
|
||||
# Note: if a cursor is read until exhausted (read until Mongo::Constants::OP_QUERY or
|
||||
# Mongo::Constants::OP_GETMORE returns zero for the cursor id), there is no need to
|
||||
@ -215,7 +218,7 @@ module Mongo
|
||||
slave_ok + timeout
|
||||
end
|
||||
|
||||
# Returns the query options set on this Cursor.
|
||||
# Returns the query options for this Cursor.
|
||||
def query_options_hash
|
||||
{ :selector => @selector,
|
||||
:fields => @fields,
|
||||
@ -245,7 +248,7 @@ module Mongo
|
||||
end
|
||||
end
|
||||
|
||||
# Set query selector hash. If the selector is a Code or String object,
|
||||
# Set the query selector hash. If the selector is a Code or String object,
|
||||
# the selector will be used in a $where clause.
|
||||
# See http://www.mongodb.org/display/DOCS/Server-side+Code+Execution
|
||||
def convert_selector_for_query(selector)
|
||||
@ -266,20 +269,21 @@ module Mongo
|
||||
@order || @explain || @hint || @snapshot
|
||||
end
|
||||
|
||||
# Return a number of documents remaining for this cursor.
|
||||
def num_remaining
|
||||
refill_via_get_more if @cache.length == 0
|
||||
@cache.length
|
||||
end
|
||||
|
||||
# Internal method, not for general use. Return +true+ if there are
|
||||
# more records to retrieve. This methods does not check @limit;
|
||||
# #each is responsible for doing that.
|
||||
# more records to retrieve. This method does not check @limit;
|
||||
# Cursor#each is responsible for doing that.
|
||||
def more?
|
||||
num_remaining > 0
|
||||
end
|
||||
|
||||
def refill_via_get_more
|
||||
return if send_query_if_needed || @cursor_id.zero?
|
||||
return if send_initial_query || @cursor_id.zero?
|
||||
message = ByteBuffer.new
|
||||
# Reserved.
|
||||
message.put_int(0)
|
||||
@ -299,7 +303,7 @@ module Mongo
|
||||
end
|
||||
|
||||
# Run query the first time we request an object from the wire
|
||||
def send_query_if_needed
|
||||
def send_initial_query
|
||||
if @query_run
|
||||
false
|
||||
else
|
||||
|
@ -334,7 +334,7 @@ module Mongo
|
||||
end
|
||||
|
||||
cursor = Cursor.new(Collection.new(self, SYSTEM_COMMAND_COLLECTION), :admin => use_admin_db, :limit => -1, :selector => selector, :socket => sock)
|
||||
cursor.next_object
|
||||
cursor.next_document
|
||||
end
|
||||
|
||||
# Sends a command to the database.
|
||||
@ -357,7 +357,7 @@ module Mongo
|
||||
end
|
||||
|
||||
result = Cursor.new(system_command_collection, :admin => admin,
|
||||
:limit => -1, :selector => selector, :socket => sock).next_object
|
||||
:limit => -1, :selector => selector, :socket => sock).next_document
|
||||
|
||||
if check_response && !ok?(result)
|
||||
raise OperationFailure, "Database command '#{selector.keys.first}' failed."
|
||||
|
@ -73,7 +73,7 @@ module GridFS
|
||||
class << self
|
||||
|
||||
def exist?(db, name, root_collection=DEFAULT_ROOT_COLLECTION)
|
||||
db.collection("#{root_collection}.files").find({'filename' => name}).next_object != nil
|
||||
db.collection("#{root_collection}.files").find({'filename' => name}).next_document != nil
|
||||
end
|
||||
|
||||
def open(db, name, mode, options={})
|
||||
@ -94,12 +94,12 @@ module GridFS
|
||||
}
|
||||
end
|
||||
|
||||
# List the contains of all GridFS files stored in the given db and
|
||||
# List the contents of all GridFS files stored in the given db and
|
||||
# root collection.
|
||||
#
|
||||
# :db :: the database to use
|
||||
#
|
||||
# :root_collection :: the root collection to use
|
||||
# :root_collection :: the root collection to use. If not specified, will use default root collection.
|
||||
def list(db, root_collection=DEFAULT_ROOT_COLLECTION)
|
||||
db.collection("#{root_collection}.files").find().map { |f|
|
||||
f['filename']
|
||||
@ -148,7 +148,7 @@ module GridFS
|
||||
@db, @filename, @mode = db, name, mode
|
||||
@root = options[:root] || DEFAULT_ROOT_COLLECTION
|
||||
|
||||
doc = collection.find({'filename' => @filename}).next_object
|
||||
doc = collection.find({'filename' => @filename}).next_document
|
||||
if doc
|
||||
@files_id = doc['_id']
|
||||
@content_type = doc['contentType']
|
||||
@ -495,7 +495,7 @@ module GridFS
|
||||
end
|
||||
|
||||
def nth_chunk(n)
|
||||
mongo_chunk = chunk_collection.find({'files_id' => @files_id, 'n' => n}).next_object
|
||||
mongo_chunk = chunk_collection.find({'files_id' => @files_id, 'n' => n}).next_document
|
||||
Chunk.new(self, mongo_chunk || {})
|
||||
end
|
||||
|
||||
|
@ -18,6 +18,7 @@ module Mongo
|
||||
|
||||
# JavaScript code to be evaluated by MongoDB
|
||||
class Code < String
|
||||
|
||||
# Hash mapping identifiers to their values
|
||||
attr_accessor :scope
|
||||
|
||||
|
@ -359,12 +359,12 @@ class TestCollection < Test::Unit::TestCase
|
||||
@@test.save(:foo => i)
|
||||
end
|
||||
|
||||
assert_equal 5, @@test.find({}, :skip => 5).next_object()["foo"]
|
||||
assert_equal nil, @@test.find({}, :skip => 10).next_object()
|
||||
assert_equal 5, @@test.find({}, :skip => 5).next_document()["foo"]
|
||||
assert_equal nil, @@test.find({}, :skip => 10).next_document()
|
||||
|
||||
assert_equal 5, @@test.find({}, :limit => 5).to_a.length
|
||||
|
||||
assert_equal 3, @@test.find({}, :skip => 3, :limit => 5).next_object()["foo"]
|
||||
assert_equal 3, @@test.find({}, :skip => 3, :limit => 5).next_document()["foo"]
|
||||
assert_equal 5, @@test.find({}, :skip => 3, :limit => 5).to_a.length
|
||||
end
|
||||
|
||||
|
@ -54,8 +54,8 @@ class TestConnection < Test::Unit::TestCase
|
||||
def test_copy_database
|
||||
@mongo.db('old').collection('copy-test').insert('a' => 1)
|
||||
@mongo.copy_database('old', 'new')
|
||||
old_object = @mongo.db('old').collection('copy-test').find.next_object
|
||||
new_object = @mongo.db('new').collection('copy-test').find.next_object
|
||||
old_object = @mongo.db('old').collection('copy-test').find.next_document
|
||||
new_object = @mongo.db('new').collection('copy-test').find.next_document
|
||||
assert_equal old_object, new_object
|
||||
end
|
||||
|
||||
|
@ -58,33 +58,40 @@ class CursorTest < Test::Unit::TestCase
|
||||
assert_equal 0, @@db['acollectionthatdoesn'].count()
|
||||
end
|
||||
|
||||
def test_next_object_deprecation
|
||||
@@coll.remove
|
||||
@@coll.insert({"a" => 1})
|
||||
|
||||
assert_equal 1, @@coll.find().next_object["a"]
|
||||
end
|
||||
|
||||
def test_sort
|
||||
@@coll.remove
|
||||
5.times{|x| @@coll.insert({"a" => x}) }
|
||||
|
||||
assert_kind_of Cursor, @@coll.find().sort(:a, 1)
|
||||
|
||||
assert_equal 0, @@coll.find().sort(:a, 1).next_object["a"]
|
||||
assert_equal 4, @@coll.find().sort(:a, -1).next_object["a"]
|
||||
assert_equal 0, @@coll.find().sort([["a", :asc]]).next_object["a"]
|
||||
assert_equal 0, @@coll.find().sort(:a, 1).next_document["a"]
|
||||
assert_equal 4, @@coll.find().sort(:a, -1).next_document["a"]
|
||||
assert_equal 0, @@coll.find().sort([["a", :asc]]).next_document["a"]
|
||||
|
||||
assert_kind_of Cursor, @@coll.find().sort([[:a, -1], [:b, 1]])
|
||||
|
||||
assert_equal 4, @@coll.find().sort(:a, 1).sort(:a, -1).next_object["a"]
|
||||
assert_equal 0, @@coll.find().sort(:a, -1).sort(:a, 1).next_object["a"]
|
||||
assert_equal 4, @@coll.find().sort(:a, 1).sort(:a, -1).next_document["a"]
|
||||
assert_equal 0, @@coll.find().sort(:a, -1).sort(:a, 1).next_document["a"]
|
||||
|
||||
cursor = @@coll.find()
|
||||
cursor.next_object()
|
||||
cursor.next_document
|
||||
assert_raise InvalidOperation do
|
||||
cursor.sort(["a"])
|
||||
end
|
||||
|
||||
assert_raise InvalidSortValueError do
|
||||
@@coll.find().sort(:a, 25).next_object
|
||||
@@coll.find().sort(:a, 25).next_document
|
||||
end
|
||||
|
||||
assert_raise InvalidSortValueError do
|
||||
@@coll.find().sort(25).next_object
|
||||
@@coll.find().sort(25).next_document
|
||||
end
|
||||
end
|
||||
|
||||
@ -106,7 +113,7 @@ class CursorTest < Test::Unit::TestCase
|
||||
end
|
||||
|
||||
cursor = @@coll.find()
|
||||
firstResult = cursor.next_object()
|
||||
firstResult = cursor.next_document
|
||||
assert_raise InvalidOperation, "Cannot modify the query once it has been run or closed." do
|
||||
cursor.limit(1)
|
||||
end
|
||||
@ -140,7 +147,7 @@ class CursorTest < Test::Unit::TestCase
|
||||
end
|
||||
|
||||
cursor = @@coll.find()
|
||||
firstResult = cursor.next_object()
|
||||
firstResult = cursor.next_document
|
||||
assert_raise InvalidOperation, "Cannot modify the query once it has been run or closed." do
|
||||
cursor.skip(1)
|
||||
end
|
||||
@ -233,7 +240,7 @@ class CursorTest < Test::Unit::TestCase
|
||||
def test_close_after_query_sent
|
||||
begin
|
||||
cursor = @@coll.find('a' => 1)
|
||||
cursor.next_object
|
||||
cursor.next_document
|
||||
cursor.close
|
||||
assert cursor.closed?
|
||||
rescue => ex
|
||||
@ -267,7 +274,7 @@ class CursorTest < Test::Unit::TestCase
|
||||
|
||||
10.times do |i|
|
||||
a = @@coll.find()
|
||||
a.next_object()
|
||||
a.next_document
|
||||
a.close()
|
||||
end
|
||||
|
||||
@ -277,7 +284,7 @@ class CursorTest < Test::Unit::TestCase
|
||||
@@db.command("cursorInfo" => 1)["byLocation_size"])
|
||||
|
||||
a = @@coll.find()
|
||||
a.next_object()
|
||||
a.next_document
|
||||
|
||||
assert_not_equal(client_cursors,
|
||||
@@db.command("cursorInfo" => 1)["clientCursors_size"])
|
||||
@ -291,7 +298,7 @@ class CursorTest < Test::Unit::TestCase
|
||||
assert_equal(by_location,
|
||||
@@db.command("cursorInfo" => 1)["byLocation_size"])
|
||||
|
||||
a = @@coll.find({}, :limit => 10).next_object()
|
||||
a = @@coll.find({}, :limit => 10).next_document
|
||||
|
||||
assert_equal(client_cursors,
|
||||
@@db.command("cursorInfo" => 1)["clientCursors_size"])
|
||||
@ -299,7 +306,7 @@ class CursorTest < Test::Unit::TestCase
|
||||
@@db.command("cursorInfo" => 1)["byLocation_size"])
|
||||
|
||||
@@coll.find() do |cursor|
|
||||
cursor.next_object()
|
||||
cursor.next_document
|
||||
end
|
||||
|
||||
assert_equal(client_cursors,
|
||||
@ -308,7 +315,7 @@ class CursorTest < Test::Unit::TestCase
|
||||
@@db.command("cursorInfo" => 1)["byLocation_size"])
|
||||
|
||||
@@coll.find() { |cursor|
|
||||
cursor.next_object()
|
||||
cursor.next_document
|
||||
}
|
||||
|
||||
assert_equal(client_cursors,
|
||||
|
@ -32,7 +32,7 @@ class DBTest < Test::Unit::TestCase
|
||||
end
|
||||
|
||||
should "create the proper cursor" do
|
||||
@cursor = mock(:next_object => {"ok" => 1})
|
||||
@cursor = mock(:next_document => {"ok" => 1})
|
||||
Cursor.expects(:new).with(@collection, :admin => true,
|
||||
:limit => -1, :selector => {:buildinfo => 1}, :socket => nil).returns(@cursor)
|
||||
command = {:buildinfo => 1}
|
||||
@ -40,7 +40,7 @@ class DBTest < Test::Unit::TestCase
|
||||
end
|
||||
|
||||
should "raise an error when the command fails" do
|
||||
@cursor = mock(:next_object => {"ok" => 0})
|
||||
@cursor = mock(:next_document => {"ok" => 0})
|
||||
Cursor.expects(:new).with(@collection, :admin => true,
|
||||
:limit => -1, :selector => {:buildinfo => 1}, :socket => nil).returns(@cursor)
|
||||
assert_raise OperationFailure do
|
||||
|
Loading…
Reference in New Issue
Block a user