ObjectID#from_time RUBY-82

This commit is contained in:
Kyle Banker 2010-01-22 14:24:17 -05:00
parent 4530adce49
commit 05342ef8f2
3 changed files with 50 additions and 4 deletions

View File

@ -51,6 +51,22 @@ module Mongo
str && str.length == len && match == str
end
# Create an object id from the given time. This is useful for doing range
# queries; it works because MongoDB's object ids begin
# with a timestamp.
#
# @param [Time] time a utc time to encode as an object id.
#
# @return [Mongo::ObjectID]
#
# @example Return all document created before Jan 1, 2010.
# time = Time.utc(2010, 1, 1)
# time_id = ObjectID.from_time(time)
# collection.find({'_id' => {'$lt' => time_id}})
def self.from_time(time)
self.new([time.to_i,0,0].pack("NNN").unpack("C12"))
end
# Adds a primary key to the given document if needed.
#
# @param [Hash] doc a document requiring an _id.
@ -163,7 +179,7 @@ module Mongo
#
# @return [Time] the time at which this object was created.
def generation_time
Time.at(@data.pack("C4").unpack("N")[0])
Time.at(@data.pack("C4").unpack("N")[0]).utc
end
private

View File

@ -123,6 +123,27 @@ class CursorTest < Test::Unit::TestCase
assert_equal MaxKey.new, results[3]['n']
end
def test_id_range_queries
@@coll.remove
t1 = Time.now
t1_id = ObjectID.from_time(t1)
@@coll.save({:t => 't1'})
@@coll.save({:t => 't1'})
@@coll.save({:t => 't1'})
sleep(2)
t2 = Time.now
t2_id = ObjectID.from_time(t2)
@@coll.save({:t => 't2'})
@@coll.save({:t => 't2'})
@@coll.save({:t => 't2'})
assert_equal 3, @@coll.find({'_id' => {'$gt' => t1_id}, '_id' => {'$lt' => t2_id}}).count
@@coll.find({'_id' => {'$gt' => t2_id}}).each do |doc|
assert_equal 't2', doc['t']
end
end
def test_limit
@@coll.remove

View File

@ -23,7 +23,7 @@ class ObjectIDTest < Test::Unit::TestCase
doc = {:name => 'Mongo'}
doc = ObjectID.create_pk(doc)
assert doc[:_id]
doc = {:name => 'Mongo', :_id => '12345'}
doc = ObjectID.create_pk(doc)
assert_equal '12345', doc[:_id]
@ -136,10 +136,19 @@ class ObjectIDTest < Test::Unit::TestCase
def test_generation_time
time = Time.now
id = ObjectID.new
generated_time = id.generation_time
assert_in_delta time.to_i, id.generation_time.to_i, 2
assert_in_delta time.to_i, generated_time.to_i, 2
assert_equal "UTC", generated_time.zone
end
def test_from_time
time = Time.now.utc
id = ObjectID.from_time(time)
assert_equal time.to_i, id.generation_time.to_i
end
def test_json
id = ObjectID.new
assert_equal %Q("#{id}"), id.to_json