support BSON MinKey and MaxKey RUBY-84
This commit is contained in:
parent
80afca2fe2
commit
bf7ffcfa82
@ -60,6 +60,8 @@ static VALUE Time;
|
|||||||
static VALUE ObjectID;
|
static VALUE ObjectID;
|
||||||
static VALUE DBRef;
|
static VALUE DBRef;
|
||||||
static VALUE Code;
|
static VALUE Code;
|
||||||
|
static VALUE MinKey;
|
||||||
|
static VALUE MaxKey;
|
||||||
static VALUE RegexpOfHolding;
|
static VALUE RegexpOfHolding;
|
||||||
static VALUE OrderedHash;
|
static VALUE OrderedHash;
|
||||||
static VALUE InvalidName;
|
static VALUE InvalidName;
|
||||||
@ -369,9 +371,18 @@ static int write_element_allow_id(VALUE key, VALUE value, VALUE extra, int allow
|
|||||||
SAFE_WRITE_AT_POS(buffer, length_location, (const char*)&obj_length, 4);
|
SAFE_WRITE_AT_POS(buffer, length_location, (const char*)&obj_length, 4);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (strcmp(cls, "Mongo::MaxKey") == 0) {
|
||||||
|
write_name_and_type(buffer, key, 0x7f);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (strcmp(cls, "Mongo::MinKey") == 0) {
|
||||||
|
write_name_and_type(buffer, key, 0xff);
|
||||||
|
break;
|
||||||
|
}
|
||||||
if (strcmp(cls, "DateTime") == 0 || strcmp(cls, "Date") == 0 || strcmp(cls, "ActiveSupport::TimeWithZone") == 0) {
|
if (strcmp(cls, "DateTime") == 0 || strcmp(cls, "Date") == 0 || strcmp(cls, "ActiveSupport::TimeWithZone") == 0) {
|
||||||
buffer_free(buffer);
|
buffer_free(buffer);
|
||||||
rb_raise(InvalidDocument, "Trying to serialize and instance of Date, DateTime, or TimeWithZone; the MongoDB Ruby driver currently supports Time objects only.",
|
rb_raise(InvalidDocument,
|
||||||
|
"Trying to serialize and instance of Date, DateTime, or TimeWithZone; the MongoDB Ruby driver currently supports Time objects only.",
|
||||||
TYPE(value));
|
TYPE(value));
|
||||||
}
|
}
|
||||||
buffer_free(buffer);
|
buffer_free(buffer);
|
||||||
@ -506,6 +517,11 @@ static VALUE method_serialize(VALUE self, VALUE doc, VALUE check_keys) {
|
|||||||
static VALUE get_value(const char* buffer, int* position, int type) {
|
static VALUE get_value(const char* buffer, int* position, int type) {
|
||||||
VALUE value;
|
VALUE value;
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
case -1:
|
||||||
|
{
|
||||||
|
value = rb_class_new_instance(0, NULL, MinKey);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case 1:
|
case 1:
|
||||||
{
|
{
|
||||||
double d;
|
double d;
|
||||||
@ -727,6 +743,11 @@ static VALUE get_value(const char* buffer, int* position, int type) {
|
|||||||
*position += 8;
|
*position += 8;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case 127:
|
||||||
|
{
|
||||||
|
value = rb_class_new_instance(0, NULL, MaxKey);
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
rb_raise(rb_eTypeError, "no c decoder for this type yet (%d)", type);
|
rb_raise(rb_eTypeError, "no c decoder for this type yet (%d)", type);
|
||||||
@ -825,6 +846,9 @@ void Init_cbson() {
|
|||||||
DBRef = rb_const_get(mongo, rb_intern("DBRef"));
|
DBRef = rb_const_get(mongo, rb_intern("DBRef"));
|
||||||
rb_require("mongo/types/code");
|
rb_require("mongo/types/code");
|
||||||
Code = rb_const_get(mongo, rb_intern("Code"));
|
Code = rb_const_get(mongo, rb_intern("Code"));
|
||||||
|
rb_require("mongo/types/min_max_keys");
|
||||||
|
MinKey = rb_const_get(mongo, rb_intern("MinKey"));
|
||||||
|
MaxKey = rb_const_get(mongo, rb_intern("MaxKey"));
|
||||||
rb_require("mongo/types/regexp_of_holding");
|
rb_require("mongo/types/regexp_of_holding");
|
||||||
RegexpOfHolding = rb_const_get(mongo, rb_intern("RegexpOfHolding"));
|
RegexpOfHolding = rb_const_get(mongo, rb_intern("RegexpOfHolding"));
|
||||||
rb_require("mongo/exceptions");
|
rb_require("mongo/exceptions");
|
||||||
|
@ -45,6 +45,7 @@ require 'mongo/types/code'
|
|||||||
require 'mongo/types/dbref'
|
require 'mongo/types/dbref'
|
||||||
require 'mongo/types/objectid'
|
require 'mongo/types/objectid'
|
||||||
require 'mongo/types/regexp_of_holding'
|
require 'mongo/types/regexp_of_holding'
|
||||||
|
require 'mongo/types/min_max_keys'
|
||||||
|
|
||||||
require 'mongo/util/support'
|
require 'mongo/util/support'
|
||||||
require 'mongo/util/conversions'
|
require 'mongo/util/conversions'
|
||||||
|
31
lib/mongo/types/min_max_keys.rb
Normal file
31
lib/mongo/types/min_max_keys.rb
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
# --
|
||||||
|
# Copyright (C) 2008-2009 10gen Inc.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
# ++
|
||||||
|
|
||||||
|
module Mongo
|
||||||
|
class MaxKey
|
||||||
|
|
||||||
|
def ==(obj)
|
||||||
|
obj.class == MaxKey
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class MinKey
|
||||||
|
|
||||||
|
def ==(obj)
|
||||||
|
obj.class == MinKey
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
@ -163,6 +163,10 @@ class BSON_RUBY
|
|||||||
serialize_null_element(@buf, k)
|
serialize_null_element(@buf, k)
|
||||||
when CODE_W_SCOPE
|
when CODE_W_SCOPE
|
||||||
serialize_code_w_scope(@buf, k, v)
|
serialize_code_w_scope(@buf, k, v)
|
||||||
|
when MAXKEY
|
||||||
|
serialize_max_key_element(@buf, k)
|
||||||
|
when MINKEY
|
||||||
|
serialize_min_key_element(@buf, k)
|
||||||
else
|
else
|
||||||
raise "unhandled type #{type}"
|
raise "unhandled type #{type}"
|
||||||
end
|
end
|
||||||
@ -234,6 +238,12 @@ class BSON_RUBY
|
|||||||
key = deserialize_cstr(@buf)
|
key = deserialize_cstr(@buf)
|
||||||
doc[key] = [deserialize_number_int_data(@buf),
|
doc[key] = [deserialize_number_int_data(@buf),
|
||||||
deserialize_number_int_data(@buf)]
|
deserialize_number_int_data(@buf)]
|
||||||
|
when MAXKEY
|
||||||
|
key = deserialize_cstr(@buf)
|
||||||
|
doc[key] = MaxKey.new
|
||||||
|
when MINKEY, 255 # This is currently easier than unpack the type byte as an unsigned char.
|
||||||
|
key = deserialize_cstr(@buf)
|
||||||
|
doc[key] = MinKey.new
|
||||||
when EOO
|
when EOO
|
||||||
break
|
break
|
||||||
else
|
else
|
||||||
@ -466,6 +476,16 @@ class BSON_RUBY
|
|||||||
self.class.serialize_cstr(buf, options_str.split(//).sort.uniq.join)
|
self.class.serialize_cstr(buf, options_str.split(//).sort.uniq.join)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def serialize_max_key_element(buf, key)
|
||||||
|
buf.put(MAXKEY)
|
||||||
|
self.class.serialize_key(buf, key)
|
||||||
|
end
|
||||||
|
|
||||||
|
def serialize_min_key_element(buf, key)
|
||||||
|
buf.put(MINKEY)
|
||||||
|
self.class.serialize_key(buf, key)
|
||||||
|
end
|
||||||
|
|
||||||
def serialize_oid_element(buf, key, val)
|
def serialize_oid_element(buf, key, val)
|
||||||
buf.put(OID)
|
buf.put(OID)
|
||||||
self.class.serialize_key(buf, key)
|
self.class.serialize_key(buf, key)
|
||||||
@ -553,6 +573,10 @@ class BSON_RUBY
|
|||||||
OBJECT
|
OBJECT
|
||||||
when Symbol
|
when Symbol
|
||||||
SYMBOL
|
SYMBOL
|
||||||
|
when MaxKey
|
||||||
|
MAXKEY
|
||||||
|
when MinKey
|
||||||
|
MINKEY
|
||||||
when Date, DateTime
|
when Date, DateTime
|
||||||
raise InvalidDocument, "Trying to serialize an instance of #{o.class}; " +
|
raise InvalidDocument, "Trying to serialize an instance of #{o.class}; " +
|
||||||
"the MongoDB Ruby driver currently supports Time objects only."
|
"the MongoDB Ruby driver currently supports Time objects only."
|
||||||
|
@ -356,6 +356,18 @@ class BSONTest < Test::Unit::TestCase
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_max_key
|
||||||
|
doc = {"a" => MaxKey.new}
|
||||||
|
|
||||||
|
assert_equal doc, BSON.deserialize(BSON.serialize(doc).to_a)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_min_key
|
||||||
|
doc = {"a" => MinKey.new}
|
||||||
|
|
||||||
|
assert_equal doc, BSON.deserialize(BSON.serialize(doc).to_a)
|
||||||
|
end
|
||||||
|
|
||||||
def test_invalid_object
|
def test_invalid_object
|
||||||
o = Object.new
|
o = Object.new
|
||||||
assert_raise InvalidDocument do
|
assert_raise InvalidDocument do
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
require 'test/test_helper'
|
require 'test/test_helper'
|
||||||
|
require 'logger'
|
||||||
|
|
||||||
# NOTE: assumes Mongo is running
|
# NOTE: assumes Mongo is running
|
||||||
class CursorTest < Test::Unit::TestCase
|
class CursorTest < Test::Unit::TestCase
|
||||||
@ -17,11 +18,6 @@ class CursorTest < Test::Unit::TestCase
|
|||||||
@@coll_full_name = 'ruby-mongo-test.test'
|
@@coll_full_name = 'ruby-mongo-test.test'
|
||||||
end
|
end
|
||||||
|
|
||||||
def teardown
|
|
||||||
@@coll.remove
|
|
||||||
@@db.error
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_explain
|
def test_explain
|
||||||
cursor = @@coll.find('a' => 1)
|
cursor = @@coll.find('a' => 1)
|
||||||
explaination = cursor.explain
|
explaination = cursor.explain
|
||||||
@ -112,6 +108,21 @@ class CursorTest < Test::Unit::TestCase
|
|||||||
assert_equal 2004, @@coll.find().sort([[:created_at, :desc]]).next_document["created_at"].year
|
assert_equal 2004, @@coll.find().sort([[:created_at, :desc]]).next_document["created_at"].year
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_sort_min_max_keys
|
||||||
|
@@coll.remove
|
||||||
|
@@coll.insert({"n" => 1000000})
|
||||||
|
@@coll.insert({"n" => -1000000})
|
||||||
|
@@coll.insert({"n" => MaxKey.new})
|
||||||
|
@@coll.insert({"n" => MinKey.new})
|
||||||
|
|
||||||
|
results = @@coll.find.sort([:n, :asc]).to_a
|
||||||
|
|
||||||
|
assert_equal MinKey.new, results[0]['n']
|
||||||
|
assert_equal -1000000, results[1]['n']
|
||||||
|
assert_equal 1000000, results[2]['n']
|
||||||
|
assert_equal MaxKey.new, results[3]['n']
|
||||||
|
end
|
||||||
|
|
||||||
def test_limit
|
def test_limit
|
||||||
@@coll.remove
|
@@coll.remove
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user