Trying to merge upstream into my code

This commit is contained in:
Adrian Madrid 2008-12-09 10:35:03 -07:00
parent 8bcabd977d
commit 8f90ce7280
4 changed files with 130 additions and 25 deletions

View File

@ -12,40 +12,87 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
require 'mongo/util/uuid'
require 'mutex_m'
require 'mongo/util/byte_buffer'
module XGen
module Mongo
module Driver
# Implementation of the Babble OID.
#
# 12 bytes
# ---
# 0 time
# 1
# 2
# 3
# 4 machine
# 5
# 6
# 7 pid
# 8
# 9 inc
# 10
# 11
class ObjectID
include Comparable
include Comparable
MACHINE = ( val = rand(0x1000000); [val & 0xff, (val >> 8) & 0xff, (val >> 16) & 0xff] )
PID = ( val = rand(0x10000); [val & 0xff, (val >> 8) & 0xff]; )
@@uuid_generator = UUID.new
LOCK = Object.new
LOCK.extend Mutex_m
# String UUID
attr_reader :uuid
@@index_time = Time.new.to_i
@@index = 0
# +uuid+ is a string. If nil, a new UUID will be generated.
def initialize(uuid=nil)
# The Babble server expects 12-byte (24 hex character) keys, which
# is why we throw away part of the UUID.
@uuid ||= @@uuid_generator.generate(:compact).sub(/(.{12}).{8}(.{12})/, '\1\2')
# +data+ is an array of bytes. If nil, a new id will be generated.
# The time +t+ is only used for testing; leave it nil.
def initialize(data=nil, t=nil)
@data = data || generate_id(t)
end
def eql?(other)
@data == other.to_a
end
alias_method :==, :eql?
def to_a
@data.dup
end
def to_s
@uuid
@data.collect { |b| '%02x' % b }.join
end
# This will make more sense when we implement the Babble algorithm for
# generating object ids.
def <=>(other)
to_s <=> other.to_s
def generate_id(t=nil)
t ||= Time.new.to_i
buf = ByteBuffer.new
buf.put_int(t & 0xffffffff)
buf.put_array(MACHINE)
buf.put_array(PID)
i = index_for_time(t)
buf.put(i & 0xff)
buf.put((i >> 8) & 0xff)
buf.put((i >> 16) & 0xff)
buf.rewind
buf.to_a.dup
end
def index_for_time(t)
LOCK.mu_synchronize {
if t != @@index_time
@@index = 0
@@index_time = t
end
retval = @@index
@@index += 1
retval
}
end
end
end
end
end
end

View File

@ -106,21 +106,27 @@ class DBAPITest < Test::Unit::TestCase
assert docs.detect { |row| row['a'] == 1 }
assert docs.detect { |row| row['a'] == 2 }
# Find by advanced query (regexp)
docs = @coll.find('a' => {'$in' => /[1|2]/}).map
docs = @coll.find('a' => /[1|2]/).map
assert_equal 2, docs.size
assert docs.detect { |row| row['a'] == 1 }
assert docs.detect { |row| row['a'] == 2 }
end
def test_find_sorting
@r2 = @coll.insert('_id' => new_oid, 'a' => 2)
@r3 = @coll.insert('_id' => new_oid, 'b' => 3)
@coll.insert('a' => 2)
@coll.insert('b' => 3)
# Sorting (ascending)
docs = @coll.find({'a' => { '$lt' => 10 }}, :sort => { 'a' => 1 }).map
order_by = OrderedHash.new
order_by['a'] = 1
docs = @coll.find({'a' => { '$lt' => 10 }}, :sort => order_by).map
assert_equal 2, docs.size
assert_equal 1, docs.first['a']
# Sorting (descending)
docs = @coll.find({'a' => { '$lt' => 10 }}, :sort => { 'a' => -1 }).map
order_by = OrderedHash.new
order_by['a'] = -1
docs = @coll.find({'a' => { '$lt' => 10 }}, :sort => order_by).map
assert_equal 2, docs.size
assert_equal 2, docs.first['a']
end

View File

@ -6,8 +6,6 @@ require 'test/unit'
class DBConnectionTest < Test::Unit::TestCase
def test_no_exceptions
host = ENV['HOST'] || ENV['host'] || 'localhost'
port = ENV['PORT'] || ENV['port'] || 27017
host = ENV['MONGO_RUBY_DRIVER_HOST'] || 'localhost'
port = ENV['MONGO_RUBY_DRIVER_PORT'] || XGen::Mongo::Driver::Mongo::DEFAULT_PORT
db = XGen::Mongo::Driver::Mongo.new(host, port).db('ruby-mongo-test')

54
tests/test_objectid.rb Normal file
View File

@ -0,0 +1,54 @@
$LOAD_PATH[0,0] = File.join(File.dirname(__FILE__), '..', 'lib')
require 'mongo'
require 'test/unit'
class ObjectIDTest < Test::Unit::TestCase
include XGen::Mongo::Driver
def setup
@t = 42
@o = ObjectID.new(nil, @t)
end
def test_index_for_time
t = 99
assert_equal 0, @o.index_for_time(t)
assert_equal 1, @o.index_for_time(t)
assert_equal 2, @o.index_for_time(t)
t = 100
assert_equal 0, @o.index_for_time(t)
end
def test_time_bytes
a = @o.to_a
assert_equal @t, a[0]
3.times { |i| assert_equal 0, a[i+1] }
t = 43
o = ObjectID.new(nil, t)
a = o.to_a
assert_equal t, a[0]
3.times { |i| assert_equal 0, a[i+1] }
assert_equal 1, o.index_for_time(t) # 0 was used for o
end
def test_different
o2 = ObjectID.new(nil, @t)
assert @o.to_a != o2.to_a
end
def test_eql?
o2 = ObjectID.new(@o.to_a)
assert @o.eql?(o2)
assert @o == o2
end
def test_to_s
s = @o.to_s
assert_equal 24, s.length
s =~ /^([0-9a-f]+)$/
assert_equal 24, $1.length
end
end