mongo 0.18.2 → 0.18.3
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +37 -28
- data/Rakefile +19 -0
- data/bin/objectid_benchmark.rb +23 -0
- data/examples/admin.rb +7 -6
- data/examples/capped.rb +3 -4
- data/examples/cursor.rb +4 -3
- data/examples/gridfs.rb +3 -2
- data/examples/index_test.rb +10 -9
- data/examples/info.rb +3 -2
- data/examples/queries.rb +3 -2
- data/examples/simple.rb +3 -2
- data/examples/strict.rb +2 -1
- data/examples/types.rb +4 -3
- data/lib/mongo.rb +29 -12
- data/lib/mongo/admin.rb +17 -2
- data/lib/mongo/collection.rb +230 -169
- data/lib/mongo/connection.rb +136 -91
- data/lib/mongo/cursor.rb +68 -40
- data/lib/mongo/db.rb +247 -123
- data/lib/mongo/{errors.rb → exceptions.rb} +6 -5
- data/lib/mongo/gridfs.rb +6 -0
- data/lib/mongo/gridfs/grid_store.rb +142 -94
- data/lib/mongo/types/binary.rb +11 -1
- data/lib/mongo/types/code.rb +6 -1
- data/lib/mongo/types/dbref.rb +7 -2
- data/lib/mongo/types/min_max_keys.rb +58 -0
- data/lib/mongo/types/objectid.rb +76 -20
- data/lib/mongo/types/regexp_of_holding.rb +5 -0
- data/lib/mongo/util/bson_ruby.rb +36 -2
- data/lib/mongo/util/byte_buffer.rb +18 -2
- data/lib/mongo/util/conversions.rb +6 -5
- data/lib/mongo/util/ordered_hash.rb +3 -1
- data/lib/mongo/util/support.rb +3 -0
- data/lib/mongo/util/xml_to_ruby.rb +7 -0
- data/test/test_bson.rb +48 -0
- data/test/test_collection.rb +13 -0
- data/test/test_connection.rb +35 -0
- data/test/test_conversions.rb +1 -1
- data/test/test_cursor.rb +37 -5
- data/test/test_db.rb +51 -2
- data/test/test_db_api.rb +4 -7
- data/test/test_grid_store.rb +10 -0
- data/test/test_objectid.rb +16 -2
- data/test/test_ordered_hash.rb +14 -0
- data/test/threading/test_threading_large_pool.rb +4 -4
- data/test/unit/db_test.rb +43 -0
- metadata +5 -7
- data/examples/benchmarks.rb +0 -42
- data/examples/blog.rb +0 -76
- data/lib/mongo/constants.rb +0 -15
- data/test/mongo-qa/_common.rb +0 -8
data/lib/mongo/types/objectid.rb
CHANGED
@@ -14,13 +14,13 @@
|
|
14
14
|
# limitations under the License.
|
15
15
|
# ++
|
16
16
|
|
17
|
-
require '
|
17
|
+
require 'thread'
|
18
18
|
require 'socket'
|
19
19
|
require 'digest/md5'
|
20
20
|
|
21
21
|
module Mongo
|
22
22
|
|
23
|
-
#
|
23
|
+
# ObjectID class for documents in MongoDB.
|
24
24
|
class ObjectID
|
25
25
|
# This is the legacy byte ordering for Babble. Versions of the Ruby
|
26
26
|
# driver prior to 0.14 used this byte ordering when converting ObjectID
|
@@ -30,11 +30,20 @@ module Mongo
|
|
30
30
|
# with ObjectID#legacy_string_convert
|
31
31
|
BYTE_ORDER = [7, 6, 5, 4, 3, 2, 1, 0, 11, 10, 9, 8]
|
32
32
|
|
33
|
-
|
34
|
-
LOCK.extend Mutex_m
|
35
|
-
|
33
|
+
@@lock = Mutex.new
|
36
34
|
@@index = 0
|
37
35
|
|
36
|
+
# Create a new object id. If no parameter is given, an id corresponding
|
37
|
+
# to the ObjectID BSON data type will be created. This is a 12-byte value
|
38
|
+
# consisting of a 4-byte timestamp, a 3-byte machine id, a 2-byte process id,
|
39
|
+
# and a 3-byte counter.
|
40
|
+
#
|
41
|
+
# @param [Array] data should be an array of bytes. If you want
|
42
|
+
# to generate a standard MongoDB object id, leave this argument blank.
|
43
|
+
def initialize(data=nil)
|
44
|
+
@data = data || generate
|
45
|
+
end
|
46
|
+
|
38
47
|
def self.legal?(str)
|
39
48
|
len = BYTE_ORDER.length * 2
|
40
49
|
str =~ /([0-9a-f]+)/i
|
@@ -42,33 +51,61 @@ module Mongo
|
|
42
51
|
str && str.length == len && match == str
|
43
52
|
end
|
44
53
|
|
54
|
+
# Create an object id from the given time. This is useful for doing range
|
55
|
+
# queries; it works because MongoDB's object ids begin
|
56
|
+
# with a timestamp.
|
57
|
+
#
|
58
|
+
# @param [Time] time a utc time to encode as an object id.
|
59
|
+
#
|
60
|
+
# @return [Mongo::ObjectID]
|
61
|
+
#
|
62
|
+
# @example Return all document created before Jan 1, 2010.
|
63
|
+
# time = Time.utc(2010, 1, 1)
|
64
|
+
# time_id = ObjectID.from_time(time)
|
65
|
+
# collection.find({'_id' => {'$lt' => time_id}})
|
66
|
+
def self.from_time(time)
|
67
|
+
self.new([time.to_i,0,0].pack("NNN").unpack("C12"))
|
68
|
+
end
|
69
|
+
|
45
70
|
# Adds a primary key to the given document if needed.
|
71
|
+
#
|
72
|
+
# @param [Hash] doc a document requiring an _id.
|
73
|
+
#
|
74
|
+
# @return [Mongo::ObjectID, Object] returns a newly-created or
|
75
|
+
# current _id for the given document.
|
46
76
|
def self.create_pk(doc)
|
47
77
|
doc.has_key?(:_id) || doc.has_key?('_id') ? doc : doc.merge!(:_id => self.new)
|
48
78
|
end
|
49
79
|
|
50
|
-
#
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
def eql?(other)
|
56
|
-
@data == other.instance_variable_get("@data")
|
80
|
+
# Check equality of this object id with another.
|
81
|
+
#
|
82
|
+
# @param [Mongo::ObjectID] object_id
|
83
|
+
def eql?(object_id)
|
84
|
+
@data == object_id.instance_variable_get("@data")
|
57
85
|
end
|
58
86
|
alias_method :==, :eql?
|
59
87
|
|
60
|
-
#
|
88
|
+
# Get a unique hashcode for this object.
|
61
89
|
# This is required since we've defined an #eql? method.
|
90
|
+
#
|
91
|
+
# @return [Integer]
|
62
92
|
def hash
|
63
93
|
@data.hash
|
64
94
|
end
|
65
95
|
|
96
|
+
# Get an array representation of the object id.
|
97
|
+
#
|
98
|
+
# @return [Array]
|
66
99
|
def to_a
|
67
100
|
@data.dup
|
68
101
|
end
|
69
102
|
|
70
103
|
# Given a string representation of an ObjectID, return a new ObjectID
|
71
104
|
# with that value.
|
105
|
+
#
|
106
|
+
# @param [String] str
|
107
|
+
#
|
108
|
+
# @return [Mongo::ObjectID]
|
72
109
|
def self.from_string(str)
|
73
110
|
raise InvalidObjectID, "illegal ObjectID format" unless legal?(str)
|
74
111
|
data = []
|
@@ -78,11 +115,13 @@ module Mongo
|
|
78
115
|
self.new(data)
|
79
116
|
end
|
80
117
|
|
118
|
+
# @deprecated
|
81
119
|
# Create a new ObjectID given a string representation of an ObjectID
|
82
120
|
# using the legacy byte ordering. This method may eventually be
|
83
121
|
# removed. If you are not sure that you need this method you should be
|
84
122
|
# using the regular from_string.
|
85
123
|
def self.from_string_legacy(str)
|
124
|
+
warn "Support for legacy object ids has been DEPRECATED."
|
86
125
|
raise InvalidObjectID, "illegal ObjectID format" unless legal?(str)
|
87
126
|
data = []
|
88
127
|
BYTE_ORDER.each_with_index { |string_position, data_index|
|
@@ -91,6 +130,9 @@ module Mongo
|
|
91
130
|
self.new(data)
|
92
131
|
end
|
93
132
|
|
133
|
+
# Get a string representation of this object id.
|
134
|
+
#
|
135
|
+
# @return [String]
|
94
136
|
def to_s
|
95
137
|
str = ' ' * 24
|
96
138
|
12.times do |i|
|
@@ -98,13 +140,22 @@ module Mongo
|
|
98
140
|
end
|
99
141
|
str
|
100
142
|
end
|
143
|
+
alias_method :inspect, :to_s
|
144
|
+
|
145
|
+
# Convert to MongoDB extended JSON format. Since JSON includes type information,
|
146
|
+
# but lacks an ObjectID type, this JSON format encodes the type using an $id key.
|
147
|
+
#
|
148
|
+
# @return [String] the object id represented as MongoDB extended JSON.
|
149
|
+
def to_json(escaped=false)
|
150
|
+
"{\"$oid\": \"#{to_s}\"}"
|
151
|
+
end
|
101
152
|
|
102
|
-
|
103
|
-
|
153
|
+
# @deprecated
|
104
154
|
# Get a string representation of this ObjectID using the legacy byte
|
105
155
|
# ordering. This method may eventually be removed. If you are not sure
|
106
156
|
# that you need this method you should be using the regular to_s.
|
107
157
|
def to_s_legacy
|
158
|
+
warn "Support for legacy object ids has been DEPRECATED."
|
108
159
|
str = ' ' * 24
|
109
160
|
BYTE_ORDER.each_with_index { |string_position, data_index|
|
110
161
|
str[string_position * 2, 2] = '%02x' % @data[data_index]
|
@@ -112,11 +163,13 @@ module Mongo
|
|
112
163
|
str
|
113
164
|
end
|
114
165
|
|
166
|
+
# @deprecated
|
115
167
|
# Convert a string representation of an ObjectID using the legacy byte
|
116
168
|
# ordering to the proper byte ordering. This method may eventually be
|
117
169
|
# removed. If you are not sure that you need this method it is probably
|
118
170
|
# unnecessary.
|
119
171
|
def self.legacy_string_convert(str)
|
172
|
+
warn "Support for legacy object ids has been DEPRECATED."
|
120
173
|
legacy = ' ' * 24
|
121
174
|
BYTE_ORDER.each_with_index do |legacy_pos, pos|
|
122
175
|
legacy[legacy_pos * 2, 2] = str[pos * 2, 2]
|
@@ -124,10 +177,13 @@ module Mongo
|
|
124
177
|
legacy
|
125
178
|
end
|
126
179
|
|
127
|
-
#
|
128
|
-
# be used in lieu of a created_at timestamp
|
180
|
+
# Return the UTC time at which this ObjectID was generated. This may
|
181
|
+
# be used in lieu of a created_at timestamp since this information
|
182
|
+
# is always encoded in the object id.
|
183
|
+
#
|
184
|
+
# @return [Time] the time at which this object was created.
|
129
185
|
def generation_time
|
130
|
-
Time.at(@data.pack("C4").unpack("N")[0])
|
186
|
+
Time.at(@data.pack("C4").unpack("N")[0]).utc
|
131
187
|
end
|
132
188
|
|
133
189
|
private
|
@@ -155,9 +211,9 @@ module Mongo
|
|
155
211
|
end
|
156
212
|
|
157
213
|
def get_inc
|
158
|
-
|
214
|
+
@@lock.synchronize do
|
159
215
|
@@index = (@@index + 1) % 0xFFFFFF
|
160
|
-
|
216
|
+
end
|
161
217
|
end
|
162
218
|
end
|
163
219
|
end
|
@@ -24,14 +24,19 @@ module Mongo
|
|
24
24
|
# Note that you do not have to use this class at all if you wish to
|
25
25
|
# store regular expressions in Mongo. The Mongo and Ruby regex option
|
26
26
|
# flags are the same. Storing regexes is discouraged, in any case.
|
27
|
+
#
|
28
|
+
# @deprecated
|
27
29
|
class RegexpOfHolding < Regexp
|
28
30
|
|
29
31
|
attr_accessor :extra_options_str
|
30
32
|
|
33
|
+
# @deprecated we're no longer supporting this.
|
31
34
|
# +str+ and +options+ are the same as Regexp. +extra_options_str+
|
32
35
|
# contains all the other flags that were in Mongo but we do not use or
|
33
36
|
# understand.
|
34
37
|
def initialize(str, options, extra_options_str)
|
38
|
+
warn "RegexpOfHolding is deprecated; the modifiers i, m, and x will be stored automatically as BSON." +
|
39
|
+
"If you're only storing the options i, m, and x, you can safely ignore this message."
|
35
40
|
super(str, options)
|
36
41
|
@extra_options_str = extra_options_str
|
37
42
|
end
|
data/lib/mongo/util/bson_ruby.rb
CHANGED
@@ -163,6 +163,10 @@ class BSON_RUBY
|
|
163
163
|
serialize_null_element(@buf, k)
|
164
164
|
when CODE_W_SCOPE
|
165
165
|
serialize_code_w_scope(@buf, k, v)
|
166
|
+
when MAXKEY
|
167
|
+
serialize_max_key_element(@buf, k)
|
168
|
+
when MINKEY
|
169
|
+
serialize_min_key_element(@buf, k)
|
166
170
|
else
|
167
171
|
raise "unhandled type #{type}"
|
168
172
|
end
|
@@ -234,6 +238,12 @@ class BSON_RUBY
|
|
234
238
|
key = deserialize_cstr(@buf)
|
235
239
|
doc[key] = [deserialize_number_int_data(@buf),
|
236
240
|
deserialize_number_int_data(@buf)]
|
241
|
+
when MAXKEY
|
242
|
+
key = deserialize_cstr(@buf)
|
243
|
+
doc[key] = MaxKey.new
|
244
|
+
when MINKEY, 255 # This is currently easier than unpack the type byte as an unsigned char.
|
245
|
+
key = deserialize_cstr(@buf)
|
246
|
+
doc[key] = MinKey.new
|
237
247
|
when EOO
|
238
248
|
break
|
239
249
|
else
|
@@ -466,6 +476,16 @@ class BSON_RUBY
|
|
466
476
|
self.class.serialize_cstr(buf, options_str.split(//).sort.uniq.join)
|
467
477
|
end
|
468
478
|
|
479
|
+
def serialize_max_key_element(buf, key)
|
480
|
+
buf.put(MAXKEY)
|
481
|
+
self.class.serialize_key(buf, key)
|
482
|
+
end
|
483
|
+
|
484
|
+
def serialize_min_key_element(buf, key)
|
485
|
+
buf.put(MINKEY)
|
486
|
+
self.class.serialize_key(buf, key)
|
487
|
+
end
|
488
|
+
|
469
489
|
def serialize_oid_element(buf, key, val)
|
470
490
|
buf.put(OID)
|
471
491
|
self.class.serialize_key(buf, key)
|
@@ -529,7 +549,7 @@ class BSON_RUBY
|
|
529
549
|
NULL
|
530
550
|
when Integer
|
531
551
|
NUMBER_INT
|
532
|
-
when
|
552
|
+
when Float
|
533
553
|
NUMBER
|
534
554
|
when ByteBuffer
|
535
555
|
BINARY
|
@@ -553,8 +573,22 @@ class BSON_RUBY
|
|
553
573
|
OBJECT
|
554
574
|
when Symbol
|
555
575
|
SYMBOL
|
576
|
+
when MaxKey
|
577
|
+
MAXKEY
|
578
|
+
when MinKey
|
579
|
+
MINKEY
|
580
|
+
when Numeric
|
581
|
+
raise InvalidDocument, "Cannot serialize the Numeric type #{o.class} as BSON; only Fixum, Bignum, and Float are supported."
|
582
|
+
when Date, DateTime
|
583
|
+
raise InvalidDocument, "#{o.class} is not currently supported; " +
|
584
|
+
"use a UTC Time instance instead."
|
556
585
|
else
|
557
|
-
|
586
|
+
if defined?(ActiveSupport::TimeWithZone) && o.is_a?(ActiveSupport::TimeWithZone)
|
587
|
+
raise InvalidDocument, "ActiveSupport::TimeWithZone is not currently supported; " +
|
588
|
+
"use a UTC Time instance instead."
|
589
|
+
else
|
590
|
+
raise InvalidDocument, "Cannot serialize #{o.class} as a BSON type; it either isn't supported or won't translate to BSON."
|
591
|
+
end
|
558
592
|
end
|
559
593
|
end
|
560
594
|
|
@@ -17,6 +17,20 @@
|
|
17
17
|
# A byte buffer.
|
18
18
|
class ByteBuffer
|
19
19
|
|
20
|
+
# Commonly-used integers.
|
21
|
+
INT_LOOKUP = {
|
22
|
+
0 => [0, 0, 0, 0],
|
23
|
+
1 => [1, 0, 0, 0],
|
24
|
+
2 => [2, 0, 0, 0],
|
25
|
+
3 => [3, 0, 0, 0],
|
26
|
+
4 => [4, 0, 0, 0],
|
27
|
+
2001 => [209, 7, 0, 0],
|
28
|
+
2002 => [210, 7, 0, 0],
|
29
|
+
2004 => [212, 7, 0, 0],
|
30
|
+
2005 => [213, 7, 0, 0],
|
31
|
+
2006 => [214, 7, 0, 0]
|
32
|
+
}
|
33
|
+
|
20
34
|
attr_reader :order
|
21
35
|
|
22
36
|
def initialize(initial_data=[])
|
@@ -100,8 +114,10 @@ class ByteBuffer
|
|
100
114
|
end
|
101
115
|
|
102
116
|
def put_int(i, offset=nil)
|
103
|
-
a = []
|
104
|
-
|
117
|
+
unless a = INT_LOOKUP[i]
|
118
|
+
a = []
|
119
|
+
[i].pack(@int_pack_order).each_byte { |b| a << b }
|
120
|
+
end
|
105
121
|
put_array(a, offset)
|
106
122
|
end
|
107
123
|
|
@@ -19,8 +19,8 @@ module Mongo #:nodoc:
|
|
19
19
|
# objects to mongo-friendly parameters.
|
20
20
|
module Conversions
|
21
21
|
|
22
|
-
|
23
|
-
|
22
|
+
ASCENDING_CONVERSION = ["ascending", "asc", "1"]
|
23
|
+
DESCENDING_CONVERSION = ["descending", "desc", "-1"]
|
24
24
|
|
25
25
|
# Converts the supplied +Array+ to a +Hash+ to pass to mongo as
|
26
26
|
# sorting parameters. The returned +Hash+ will vary depending
|
@@ -76,11 +76,12 @@ module Mongo #:nodoc:
|
|
76
76
|
# If the value is invalid then an error will be raised.
|
77
77
|
def sort_value(value)
|
78
78
|
val = value.to_s.downcase
|
79
|
-
return 1 if
|
80
|
-
return -1 if
|
79
|
+
return 1 if ASCENDING_CONVERSION.include?(val)
|
80
|
+
return -1 if DESCENDING_CONVERSION.include?(val)
|
81
81
|
raise InvalidSortValueError.new(
|
82
82
|
"#{self} was supplied as a sort direction when acceptable values are: " +
|
83
|
-
"Mongo::ASCENDING, 'ascending', 'asc', :ascending, :asc, 1, Mongo::DESCENDING,
|
83
|
+
"Mongo::ASCENDING, 'ascending', 'asc', :ascending, :asc, 1, Mongo::DESCENDING, " +
|
84
|
+
"'descending', 'desc', :descending, :desc, -1.")
|
84
85
|
end
|
85
86
|
end
|
86
87
|
end
|
@@ -88,6 +88,8 @@ class OrderedHash < Hash
|
|
88
88
|
super(other)
|
89
89
|
end
|
90
90
|
|
91
|
+
alias :update :merge!
|
92
|
+
|
91
93
|
def inspect
|
92
94
|
str = '{'
|
93
95
|
str << (@ordered_keys || []).collect { |k| "\"#{k}\"=>#{self.[](k).inspect}" }.join(", ")
|
@@ -118,7 +120,7 @@ class OrderedHash < Hash
|
|
118
120
|
code = 37 * code + key.hash
|
119
121
|
code = 37 * code + value.hash
|
120
122
|
end
|
121
|
-
code
|
123
|
+
code & 0x7fffffff
|
122
124
|
end
|
123
125
|
|
124
126
|
def eql?(o)
|
data/lib/mongo/util/support.rb
CHANGED
@@ -17,6 +17,7 @@
|
|
17
17
|
require 'rexml/document'
|
18
18
|
require 'mongo'
|
19
19
|
|
20
|
+
# @deprecated
|
20
21
|
# Converts a .xson file (an XML file that describes a Mongo-type document) to
|
21
22
|
# an OrderedHash.
|
22
23
|
class XMLToRuby
|
@@ -24,6 +25,7 @@ class XMLToRuby
|
|
24
25
|
include Mongo
|
25
26
|
|
26
27
|
def xml_to_ruby(io)
|
28
|
+
warn "XMLToRuby is deprecated. The .xson format is not longer in use."
|
27
29
|
doc = REXML::Document.new(io)
|
28
30
|
doc_to_ruby(doc.root.elements['doc'])
|
29
31
|
end
|
@@ -31,6 +33,7 @@ class XMLToRuby
|
|
31
33
|
protected
|
32
34
|
|
33
35
|
def element_to_ruby(e)
|
36
|
+
warn "XMLToRuby is deprecated. The .xson format is not longer in use."
|
34
37
|
type = e.name
|
35
38
|
child = e.elements[1]
|
36
39
|
case type
|
@@ -71,12 +74,14 @@ class XMLToRuby
|
|
71
74
|
end
|
72
75
|
|
73
76
|
def doc_to_ruby(element)
|
77
|
+
warn "XMLToRuby is deprecated. The .xson format is not longer in use."
|
74
78
|
oh = OrderedHash.new
|
75
79
|
element.elements.each { |e| oh[e.attributes['name']] = element_to_ruby(e) }
|
76
80
|
oh
|
77
81
|
end
|
78
82
|
|
79
83
|
def array_to_ruby(elements)
|
84
|
+
warn "XMLToRuby is deprecated. The .xson format is not longer in use."
|
80
85
|
a = []
|
81
86
|
elements.each { |e|
|
82
87
|
index_str = e.attributes['name']
|
@@ -86,6 +91,7 @@ class XMLToRuby
|
|
86
91
|
end
|
87
92
|
|
88
93
|
def regex_to_ruby(elements)
|
94
|
+
warn "XMLToRuby is deprecated. The .xson format is not longer in use."
|
89
95
|
pattern = elements['pattern'].text
|
90
96
|
options_str = elements['options'].text || ''
|
91
97
|
|
@@ -97,6 +103,7 @@ class XMLToRuby
|
|
97
103
|
end
|
98
104
|
|
99
105
|
def dbref_to_ruby(elements)
|
106
|
+
warn "XMLToRuby is deprecated. The .xson format is not longer in use."
|
100
107
|
ns = elements['ns'].text
|
101
108
|
oid_str = elements['oid'].text
|
102
109
|
DBRef.new(ns, ObjectID.from_string(oid_str))
|
data/test/test_bson.rb
CHANGED
@@ -1,5 +1,15 @@
|
|
1
1
|
# encoding:utf-8
|
2
2
|
require 'test/test_helper'
|
3
|
+
require 'complex'
|
4
|
+
require 'bigdecimal'
|
5
|
+
require 'rational'
|
6
|
+
|
7
|
+
# Need to simulating this class
|
8
|
+
# without actually loading it.
|
9
|
+
module ActiveSupport
|
10
|
+
class TimeWithZone
|
11
|
+
end
|
12
|
+
end
|
3
13
|
|
4
14
|
class BSONTest < Test::Unit::TestCase
|
5
15
|
|
@@ -181,6 +191,19 @@ class BSONTest < Test::Unit::TestCase
|
|
181
191
|
end
|
182
192
|
end
|
183
193
|
|
194
|
+
def test_exeption_on_using_unsupported_date_class
|
195
|
+
[DateTime.now, Date.today, ActiveSupport::TimeWithZone.new].each do |invalid_date|
|
196
|
+
doc = {:date => invalid_date}
|
197
|
+
begin
|
198
|
+
bson = BSON.serialize(doc)
|
199
|
+
rescue => e
|
200
|
+
ensure
|
201
|
+
assert_equal InvalidDocument, e.class
|
202
|
+
assert_match /UTC Time/, e.message
|
203
|
+
end
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
184
207
|
def test_dbref
|
185
208
|
oid = ObjectID.new
|
186
209
|
doc = {}
|
@@ -293,6 +316,19 @@ class BSONTest < Test::Unit::TestCase
|
|
293
316
|
end
|
294
317
|
end
|
295
318
|
|
319
|
+
def test_invalid_numeric_types
|
320
|
+
[BigDecimal.new("1.0"), Complex(0, 1), Rational(2, 3)].each do |type|
|
321
|
+
doc = {"x" => type}
|
322
|
+
begin
|
323
|
+
BSON.serialize(doc)
|
324
|
+
rescue => e
|
325
|
+
ensure
|
326
|
+
assert_equal InvalidDocument, e.class
|
327
|
+
assert_match /Cannot serialize/, e.message
|
328
|
+
end
|
329
|
+
end
|
330
|
+
end
|
331
|
+
|
296
332
|
def test_do_not_change_original_object
|
297
333
|
val = OrderedHash.new
|
298
334
|
val['not_id'] = 1
|
@@ -335,6 +371,18 @@ class BSONTest < Test::Unit::TestCase
|
|
335
371
|
end
|
336
372
|
end
|
337
373
|
|
374
|
+
def test_max_key
|
375
|
+
doc = {"a" => MaxKey.new}
|
376
|
+
|
377
|
+
assert_equal doc, BSON.deserialize(BSON.serialize(doc).to_a)
|
378
|
+
end
|
379
|
+
|
380
|
+
def test_min_key
|
381
|
+
doc = {"a" => MinKey.new}
|
382
|
+
|
383
|
+
assert_equal doc, BSON.deserialize(BSON.serialize(doc).to_a)
|
384
|
+
end
|
385
|
+
|
338
386
|
def test_invalid_object
|
339
387
|
o = Object.new
|
340
388
|
assert_raise InvalidDocument do
|