Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Added object id conversion support. Provide the keys that should be c…

…onverted with Query#object_ids and it will do the rest.
  • Loading branch information...
commit ae3651e414340fb5b63174c3083f36e70f4223ef 1 parent d923fd1
@jnunemaker jnunemaker authored
View
11 lib/plucky.rb
@@ -17,7 +17,16 @@ class Symbol
end
module Plucky
- autoload :Collection, 'plucky/collection'
autoload :CriteriaMerger, 'plucky/criteria_merger'
autoload :Query, 'plucky/query'
+
+ def self.to_object_id(value)
+ if value.nil? || (value.respond_to?(:empty?) && value.empty?)
+ nil
+ elsif value.is_a?(BSON::ObjectID)
+ value
+ else
+ BSON::ObjectID.from_string(value.to_s)
+ end
+ end
end
View
24 lib/plucky/query.rb
@@ -7,13 +7,18 @@ class Query
:fields, :skip, :limit, :sort, :hint, :snapshot, :batch_size, :timeout # Ruby Driver
]
- attr_reader :criteria, :options, :collection
+ attr_reader :criteria, :options, :collection
def initialize(collection, opts={})
@collection, @options, @criteria, = collection, {}, {}
update(opts)
end
+ def object_ids(*keys)
+ @object_id_keys = keys.flatten.map { |k| k.to_sym }
+ self
+ end
+
def find(opts={})
update(opts).collection.find(criteria, options)
end
@@ -92,13 +97,30 @@ def merge(other)
end
private
+ def object_id_key?(key)
+ return false if @object_id_keys.nil?
+ key = key.respond_to?(:field) ? key.field.to_sym : key.to_sym
+ @object_id_keys.include?(key)
+ end
+
def normalized_criteria(criteria, parent=nil)
{}.tap do |hash|
criteria.each_pair do |key, value|
key = normalized_key(key)
+
+ if object_id_key?(key)
+ case value
+ when String
+ value = Plucky.to_object_id(value)
+ when Array
+ value.map! { |id| Plucky.to_object_id(id) }
+ end
+ end
+
if symbol_operator?(key)
key, value = normalized_key(key.field), {"$#{key.operator}" => value}
end
+
hash[key] = normalized_value(hash, key, value)
end
end
View
68 test/test_query.rb → test/plucky/test_query.rb
@@ -248,6 +248,13 @@ class QueryTest < Test::Unit::TestCase
should "normalize and update options" do
Query.new(@collection).update(:order => :age.desc).options[:sort].should == [['age', -1]]
end
+
+ should "work with simple stuff" do
+ Query.new(@collection).update(:foo => 'bar').update(:baz => 'wick').criteria.should == {
+ :foo => 'bar',
+ :baz => 'wick',
+ }
+ end
end
context "#merge" do
@@ -351,6 +358,67 @@ class QueryTest < Test::Unit::TestCase
Query.new(@collection, :numbers => {'$any' => Set.new([1,2,3])}).criteria.should == {:numbers => {'$any' => [1,2,3]}}
end
end
+
+ context "with string ids for string keys" do
+ setup do
+ @id = BSON::ObjectID.new.to_s
+ @room_id = BSON::ObjectID.new.to_s
+ @query = Query.new(@collection)
+ @query.where(:_id => @id, :room_id => @room_id)
+ end
+
+ should "convert strings to object ids" do
+ @query[:_id].should == @id
+ @query[:room_id].should == @room_id
+ @query[:_id].should be_instance_of(String)
+ @query[:room_id].should be_instance_of(String)
+ end
+ end
+
+ context "with string ids for object id keys (*keys)" do
+ setup do
+ @id = BSON::ObjectID.new
+ @room_id = BSON::ObjectID.new
+ @query = Query.new(@collection).object_ids(:_id, :room_id)
+ @query.where(:_id => @id.to_s, :room_id => @room_id.to_s)
+ end
+
+ should "convert strings to object ids" do
+ @query[:_id].should == @id
+ @query[:room_id].should == @room_id
+ @query[:_id].should be_instance_of(BSON::ObjectID)
+ @query[:room_id].should be_instance_of(BSON::ObjectID)
+ end
+ end
+
+ context "with string ids for object id keys (array of keys)" do
+ setup do
+ @id = BSON::ObjectID.new
+ @room_id = BSON::ObjectID.new
+ @query = Query.new(@collection).object_ids([:_id, :room_id])
+ @query.where(:_id => @id.to_s, :room_id => @room_id.to_s)
+ end
+
+ should "convert strings to object ids" do
+ @query[:_id].should == @id
+ @query[:room_id].should == @room_id
+ @query[:_id].should be_instance_of(BSON::ObjectID)
+ @query[:room_id].should be_instance_of(BSON::ObjectID)
+ end
+ end
+
+ context "with string ids for object id keys (array)" do
+ setup do
+ @id1 = BSON::ObjectID.new
+ @id2 = BSON::ObjectID.new
+ @query = Query.new(@collection).object_ids(:_id)
+ @query.where(:_id.in => [@id1.to_s, @id2.to_s])
+ end
+
+ should "convert strings to object ids" do
+ @query[:_id].should == {'$in' => [@id1, @id2]}
+ end
+ end
end
context "order option" do
View
27 test/test_plucky.rb
@@ -0,0 +1,27 @@
+require 'helper'
+
+class PluckyTest < Test::Unit::TestCase
+ context "Plucky" do
+ context ".to_object_id" do
+ setup do
+ @id = BSON::ObjectID.new
+ end
+
+ should "convert nil to nil" do
+ Plucky.to_object_id(nil).should be_nil
+ end
+
+ should "convert blank to nil" do
+ Plucky.to_object_id('').should be_nil
+ end
+
+ should "leave object id alone" do
+ Plucky.to_object_id(@id).should equal(@id)
+ end
+
+ should "convert string to object id" do
+ Plucky.to_object_id(@id.to_s).should == @id
+ end
+ end
+ end
+end
Please sign in to comment.
Something went wrong with that request. Please try again.