mongo 0.18 → 0.18.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.rdoc +12 -4
- data/Rakefile +25 -7
- data/lib/mongo.rb +24 -15
- data/lib/mongo/admin.rb +0 -2
- data/lib/mongo/collection.rb +9 -9
- data/lib/mongo/connection.rb +5 -5
- data/lib/mongo/cursor.rb +4 -7
- data/lib/mongo/db.rb +0 -3
- data/lib/mongo/errors.rb +3 -0
- data/lib/mongo/gridfs/chunk.rb +0 -1
- data/lib/mongo/types/objectid.rb +6 -0
- data/lib/mongo/util/bson_c.rb +18 -0
- data/lib/mongo/util/{bson.rb → bson_ruby.rb} +110 -117
- data/lib/mongo/util/byte_buffer.rb +23 -0
- data/test/test_admin.rb +1 -3
- data/test/test_bson.rb +105 -70
- data/test/test_byte_buffer.rb +1 -3
- data/test/test_chunk.rb +1 -3
- data/test/test_collection.rb +11 -17
- data/test/test_connection.rb +1 -3
- data/test/test_conversions.rb +1 -2
- data/test/test_cursor.rb +1 -3
- data/test/test_db.rb +1 -3
- data/test/test_db_api.rb +1 -3
- data/test/test_db_connection.rb +1 -3
- data/test/test_grid_store.rb +1 -3
- data/test/test_helper.rb +5 -3
- data/test/test_objectid.rb +7 -3
- data/test/test_ordered_hash.rb +1 -3
- data/test/test_round_trip.rb +8 -14
- data/test/test_slave_connection.rb +1 -3
- data/test/unit/connection_test.rb +17 -1
- metadata +6 -7
@@ -27,6 +27,25 @@ class ByteBuffer
|
|
27
27
|
@double_pack_order = 'E'
|
28
28
|
end
|
29
29
|
|
30
|
+
if RUBY_VERSION >= '1.9'
|
31
|
+
def self.to_utf8(str)
|
32
|
+
str.encode("utf-8")
|
33
|
+
end
|
34
|
+
else
|
35
|
+
def self.to_utf8(str)
|
36
|
+
begin
|
37
|
+
str.unpack("U*")
|
38
|
+
rescue => ex
|
39
|
+
raise InvalidStringEncoding, "String not valid utf-8: #{str}"
|
40
|
+
end
|
41
|
+
str
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.serialize_cstr(buf, val)
|
46
|
+
buf.put_array(to_utf8(val.to_s).unpack("C*") + [0])
|
47
|
+
end
|
48
|
+
|
30
49
|
# +endianness+ should be :little_endian or :big_endian. Default is :little_endian
|
31
50
|
def order=(endianness)
|
32
51
|
@order = endianness
|
@@ -160,6 +179,10 @@ class ByteBuffer
|
|
160
179
|
end
|
161
180
|
end
|
162
181
|
|
182
|
+
def unpack(args)
|
183
|
+
to_a
|
184
|
+
end
|
185
|
+
|
163
186
|
def to_s
|
164
187
|
if @buf.respond_to? :fast_pack
|
165
188
|
@buf.fast_pack
|
data/test/test_admin.rb
CHANGED
data/test/test_bson.rb
CHANGED
@@ -1,53 +1,89 @@
|
|
1
|
-
|
2
|
-
require '
|
3
|
-
require 'mongo/util/ordered_hash'
|
4
|
-
require 'test/unit'
|
1
|
+
# encoding:utf-8
|
2
|
+
require 'test/test_helper'
|
5
3
|
|
6
4
|
class BSONTest < Test::Unit::TestCase
|
7
5
|
|
8
6
|
include Mongo
|
9
7
|
|
10
|
-
def setup
|
11
|
-
# We don't pass a DB to the constructor, even though we are about to test
|
12
|
-
# deserialization. This means that when we deserialize, any DBRefs will
|
13
|
-
# have nil @db ivars. That's fine for now.
|
14
|
-
@b = BSON.new
|
15
|
-
end
|
16
|
-
|
17
8
|
def test_string
|
18
9
|
doc = {'doc' => 'hello, world'}
|
19
|
-
|
20
|
-
assert_equal doc,
|
10
|
+
bson = bson = BSON.serialize(doc)
|
11
|
+
assert_equal doc, BSON.deserialize(bson)
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_valid_utf8_string
|
15
|
+
doc = {'doc' => 'aé'}
|
16
|
+
bson = bson = BSON.serialize(doc)
|
17
|
+
assert_equal doc, BSON.deserialize(bson)
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_valid_utf8_key
|
21
|
+
doc = {'aé' => 'hello'}
|
22
|
+
bson = bson = BSON.serialize(doc)
|
23
|
+
assert_equal doc, BSON.deserialize(bson)
|
24
|
+
end
|
25
|
+
|
26
|
+
# In 1.8 we test that other string encodings raise an exception.
|
27
|
+
# In 1.9 we test that they get auto-converted.
|
28
|
+
if RUBY_VERSION < '1.9'
|
29
|
+
require 'iconv'
|
30
|
+
def test_invalid_string
|
31
|
+
string = Iconv.conv('iso-8859-1', 'utf-8', 'aé')
|
32
|
+
doc = {'doc' => string}
|
33
|
+
assert_raise InvalidStringEncoding do
|
34
|
+
BSON.serialize(doc)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_invalid_key
|
39
|
+
key = Iconv.conv('iso-8859-1', 'utf-8', 'aé')
|
40
|
+
doc = {key => 'hello'}
|
41
|
+
assert_raise InvalidStringEncoding do
|
42
|
+
BSON.serialize(doc)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
else
|
46
|
+
def test_non_utf8_string
|
47
|
+
bson = BSON.serialize({'str' => 'aé'.encode('iso-8859-1')})
|
48
|
+
result = BSON.deserialize(bson)['str']
|
49
|
+
assert_equal 'aé', result
|
50
|
+
assert_equal 'UTF-8', result.encoding.name
|
51
|
+
end
|
52
|
+
|
53
|
+
def test_non_utf8_key
|
54
|
+
bson = BSON.serialize({'aé'.encode('iso-8859-1') => 'hello'})
|
55
|
+
assert_equal 'hello', BSON.deserialize(bson)['aé']
|
56
|
+
end
|
21
57
|
end
|
22
58
|
|
23
59
|
def test_code
|
24
60
|
doc = {'$where' => Code.new('this.a.b < this.b')}
|
25
|
-
|
26
|
-
assert_equal doc,
|
61
|
+
bson = BSON.serialize(doc)
|
62
|
+
assert_equal doc, BSON.deserialize(bson)
|
27
63
|
end
|
28
64
|
|
29
65
|
def test_number
|
30
66
|
doc = {'doc' => 41.99}
|
31
|
-
|
32
|
-
assert_equal doc,
|
67
|
+
bson = BSON.serialize(doc)
|
68
|
+
assert_equal doc, BSON.deserialize(bson)
|
33
69
|
end
|
34
70
|
|
35
71
|
def test_int
|
36
72
|
doc = {'doc' => 42}
|
37
|
-
|
38
|
-
assert_equal doc,
|
73
|
+
bson = BSON.serialize(doc)
|
74
|
+
assert_equal doc, BSON.deserialize(bson)
|
39
75
|
|
40
76
|
doc = {"doc" => -5600}
|
41
|
-
|
42
|
-
assert_equal doc,
|
77
|
+
bson = BSON.serialize(doc)
|
78
|
+
assert_equal doc, BSON.deserialize(bson)
|
43
79
|
|
44
80
|
doc = {"doc" => 2147483647}
|
45
|
-
|
46
|
-
assert_equal doc,
|
81
|
+
bson = BSON.serialize(doc)
|
82
|
+
assert_equal doc, BSON.deserialize(bson)
|
47
83
|
|
48
84
|
doc = {"doc" => -2147483648}
|
49
|
-
|
50
|
-
assert_equal doc,
|
85
|
+
bson = BSON.serialize(doc)
|
86
|
+
assert_equal doc, BSON.deserialize(bson)
|
51
87
|
end
|
52
88
|
|
53
89
|
def test_ordered_hash
|
@@ -56,32 +92,32 @@ class BSONTest < Test::Unit::TestCase
|
|
56
92
|
doc["a"] = 2
|
57
93
|
doc["c"] = 3
|
58
94
|
doc["d"] = 4
|
59
|
-
|
60
|
-
assert_equal doc,
|
95
|
+
bson = BSON.serialize(doc)
|
96
|
+
assert_equal doc, BSON.deserialize(bson)
|
61
97
|
end
|
62
98
|
|
63
99
|
def test_object
|
64
100
|
doc = {'doc' => {'age' => 42, 'name' => 'Spongebob', 'shoe_size' => 9.5}}
|
65
|
-
|
66
|
-
assert_equal doc,
|
101
|
+
bson = BSON.serialize(doc)
|
102
|
+
assert_equal doc, BSON.deserialize(bson)
|
67
103
|
end
|
68
104
|
|
69
105
|
def test_oid
|
70
106
|
doc = {'doc' => ObjectID.new}
|
71
|
-
|
72
|
-
assert_equal doc,
|
107
|
+
bson = BSON.serialize(doc)
|
108
|
+
assert_equal doc, BSON.deserialize(bson)
|
73
109
|
end
|
74
110
|
|
75
111
|
def test_array
|
76
112
|
doc = {'doc' => [1, 2, 'a', 'b']}
|
77
|
-
|
78
|
-
assert_equal doc,
|
113
|
+
bson = BSON.serialize(doc)
|
114
|
+
assert_equal doc, BSON.deserialize(bson)
|
79
115
|
end
|
80
116
|
|
81
117
|
def test_regex
|
82
118
|
doc = {'doc' => /foobar/i}
|
83
|
-
|
84
|
-
doc2 =
|
119
|
+
bson = BSON.serialize(doc)
|
120
|
+
doc2 = BSON.deserialize(bson)
|
85
121
|
assert_equal doc, doc2
|
86
122
|
|
87
123
|
r = doc2['doc']
|
@@ -91,11 +127,10 @@ class BSONTest < Test::Unit::TestCase
|
|
91
127
|
r.extra_options_str << 'zywcab'
|
92
128
|
assert_equal 'zywcab', r.extra_options_str
|
93
129
|
|
94
|
-
b = BSON.new
|
95
130
|
doc = {'doc' => r}
|
96
|
-
|
131
|
+
bson_doc = BSON.serialize(doc)
|
97
132
|
doc2 = nil
|
98
|
-
doc2 =
|
133
|
+
doc2 = BSON.deserialize(bson_doc)
|
99
134
|
assert_equal doc, doc2
|
100
135
|
|
101
136
|
r = doc2['doc']
|
@@ -105,30 +140,30 @@ class BSONTest < Test::Unit::TestCase
|
|
105
140
|
|
106
141
|
def test_boolean
|
107
142
|
doc = {'doc' => true}
|
108
|
-
|
109
|
-
assert_equal doc,
|
143
|
+
bson = BSON.serialize(doc)
|
144
|
+
assert_equal doc, BSON.deserialize(bson)
|
110
145
|
end
|
111
146
|
|
112
147
|
def test_date
|
113
148
|
doc = {'date' => Time.now}
|
114
|
-
|
115
|
-
doc2 =
|
149
|
+
bson = BSON.serialize(doc)
|
150
|
+
doc2 = BSON.deserialize(bson)
|
116
151
|
# Mongo only stores up to the millisecond
|
117
152
|
assert_in_delta doc['date'], doc2['date'], 0.001
|
118
153
|
end
|
119
154
|
|
120
155
|
def test_date_returns_as_utc
|
121
156
|
doc = {'date' => Time.now}
|
122
|
-
|
123
|
-
doc2 =
|
157
|
+
bson = BSON.serialize(doc)
|
158
|
+
doc2 = BSON.deserialize(bson)
|
124
159
|
assert doc2['date'].utc?
|
125
160
|
end
|
126
161
|
|
127
162
|
def test_date_before_epoch
|
128
163
|
begin
|
129
164
|
doc = {'date' => Time.utc(1600)}
|
130
|
-
|
131
|
-
doc2 =
|
165
|
+
bson = BSON.serialize(doc)
|
166
|
+
doc2 = BSON.deserialize(bson)
|
132
167
|
# Mongo only stores up to the millisecond
|
133
168
|
assert_in_delta doc['date'], doc2['date'], 0.001
|
134
169
|
rescue ArgumentError
|
@@ -143,16 +178,16 @@ class BSONTest < Test::Unit::TestCase
|
|
143
178
|
oid = ObjectID.new
|
144
179
|
doc = {}
|
145
180
|
doc['dbref'] = DBRef.new('namespace', oid)
|
146
|
-
|
147
|
-
doc2 =
|
181
|
+
bson = BSON.serialize(doc)
|
182
|
+
doc2 = BSON.deserialize(bson)
|
148
183
|
assert_equal 'namespace', doc2['dbref'].namespace
|
149
184
|
assert_equal oid, doc2['dbref'].object_id
|
150
185
|
end
|
151
186
|
|
152
187
|
def test_symbol
|
153
188
|
doc = {'sym' => :foo}
|
154
|
-
|
155
|
-
doc2 =
|
189
|
+
bson = BSON.serialize(doc)
|
190
|
+
doc2 = BSON.deserialize(bson)
|
156
191
|
assert_equal :foo, doc2['sym']
|
157
192
|
end
|
158
193
|
|
@@ -161,8 +196,8 @@ class BSONTest < Test::Unit::TestCase
|
|
161
196
|
'binstring'.each_byte { |b| bin.put(b) }
|
162
197
|
|
163
198
|
doc = {'bin' => bin}
|
164
|
-
|
165
|
-
doc2 =
|
199
|
+
bson = BSON.serialize(doc)
|
200
|
+
doc2 = BSON.deserialize(bson)
|
166
201
|
bin2 = doc2['bin']
|
167
202
|
assert_kind_of Binary, bin2
|
168
203
|
assert_equal 'binstring', bin2.to_s
|
@@ -173,8 +208,8 @@ class BSONTest < Test::Unit::TestCase
|
|
173
208
|
bin = Binary.new([1, 2, 3, 4, 5], Binary::SUBTYPE_USER_DEFINED)
|
174
209
|
|
175
210
|
doc = {'bin' => bin}
|
176
|
-
|
177
|
-
doc2 =
|
211
|
+
bson = BSON.serialize(doc)
|
212
|
+
doc2 = BSON.deserialize(bson)
|
178
213
|
bin2 = doc2['bin']
|
179
214
|
assert_kind_of Binary, bin2
|
180
215
|
assert_equal [1, 2, 3, 4, 5], bin2.to_a
|
@@ -186,8 +221,8 @@ class BSONTest < Test::Unit::TestCase
|
|
186
221
|
5.times { |i| bb.put(i + 1) }
|
187
222
|
|
188
223
|
doc = {'bin' => bb}
|
189
|
-
|
190
|
-
doc2 =
|
224
|
+
bson = BSON.serialize(doc)
|
225
|
+
doc2 = BSON.deserialize(bson)
|
191
226
|
bin2 = doc2['bin']
|
192
227
|
assert_kind_of Binary, bin2
|
193
228
|
assert_equal [1, 2, 3, 4, 5], bin2.to_a
|
@@ -198,24 +233,24 @@ class BSONTest < Test::Unit::TestCase
|
|
198
233
|
val = OrderedHash.new
|
199
234
|
val['not_id'] = 1
|
200
235
|
val['_id'] = 2
|
201
|
-
roundtrip =
|
236
|
+
roundtrip = BSON.deserialize(BSON.serialize(val).to_a)
|
202
237
|
assert_kind_of OrderedHash, roundtrip
|
203
238
|
assert_equal '_id', roundtrip.keys.first
|
204
239
|
|
205
240
|
val = {'a' => 'foo', 'b' => 'bar', :_id => 42, 'z' => 'hello'}
|
206
|
-
roundtrip =
|
241
|
+
roundtrip = BSON.deserialize(BSON.serialize(val).to_a)
|
207
242
|
assert_kind_of OrderedHash, roundtrip
|
208
243
|
assert_equal '_id', roundtrip.keys.first
|
209
244
|
end
|
210
245
|
|
211
246
|
def test_nil_id
|
212
247
|
doc = {"_id" => nil}
|
213
|
-
assert_equal doc,
|
248
|
+
assert_equal doc, BSON.deserialize(bson = BSON.serialize(doc).to_a)
|
214
249
|
end
|
215
250
|
|
216
251
|
def test_timestamp
|
217
252
|
val = {"test" => [4, 20]}
|
218
|
-
assert_equal val,
|
253
|
+
assert_equal val, BSON.deserialize([0x13, 0x00, 0x00, 0x00,
|
219
254
|
0x11, 0x74, 0x65, 0x73,
|
220
255
|
0x74, 0x00, 0x04, 0x00,
|
221
256
|
0x00, 0x00, 0x14, 0x00,
|
@@ -225,29 +260,29 @@ class BSONTest < Test::Unit::TestCase
|
|
225
260
|
def test_overflow
|
226
261
|
doc = {"x" => 2**75}
|
227
262
|
assert_raise RangeError do
|
228
|
-
|
263
|
+
bson = BSON.serialize(doc)
|
229
264
|
end
|
230
265
|
|
231
266
|
doc = {"x" => 9223372036854775}
|
232
|
-
assert_equal doc,
|
267
|
+
assert_equal doc, BSON.deserialize(BSON.serialize(doc).to_a)
|
233
268
|
|
234
269
|
doc = {"x" => 9223372036854775807}
|
235
|
-
assert_equal doc,
|
270
|
+
assert_equal doc, BSON.deserialize(BSON.serialize(doc).to_a)
|
236
271
|
|
237
272
|
doc["x"] = doc["x"] + 1
|
238
273
|
assert_raise RangeError do
|
239
|
-
|
274
|
+
bson = BSON.serialize(doc)
|
240
275
|
end
|
241
276
|
|
242
277
|
doc = {"x" => -9223372036854775}
|
243
|
-
assert_equal doc,
|
278
|
+
assert_equal doc, BSON.deserialize(BSON.serialize(doc).to_a)
|
244
279
|
|
245
280
|
doc = {"x" => -9223372036854775808}
|
246
|
-
assert_equal doc,
|
281
|
+
assert_equal doc, BSON.deserialize(BSON.serialize(doc).to_a)
|
247
282
|
|
248
283
|
doc["x"] = doc["x"] - 1
|
249
284
|
assert_raise RangeError do
|
250
|
-
|
285
|
+
bson = BSON.serialize(doc)
|
251
286
|
end
|
252
287
|
end
|
253
288
|
|
@@ -256,12 +291,12 @@ class BSONTest < Test::Unit::TestCase
|
|
256
291
|
val['not_id'] = 1
|
257
292
|
val['_id'] = 2
|
258
293
|
assert val.keys.include?('_id')
|
259
|
-
|
294
|
+
BSON.serialize(val)
|
260
295
|
assert val.keys.include?('_id')
|
261
296
|
|
262
297
|
val = {'a' => 'foo', 'b' => 'bar', :_id => 42, 'z' => 'hello'}
|
263
298
|
assert val.keys.include?(:_id)
|
264
|
-
|
299
|
+
BSON.serialize(val)
|
265
300
|
assert val.keys.include?(:_id)
|
266
301
|
end
|
267
302
|
|
@@ -276,7 +311,7 @@ class BSONTest < Test::Unit::TestCase
|
|
276
311
|
dup = {"_id" => "foo", :_id => "foo"}
|
277
312
|
one = {"_id" => "foo"}
|
278
313
|
|
279
|
-
assert_equal
|
314
|
+
assert_equal BSON.serialize(one).to_a, BSON.serialize(dup).to_a
|
280
315
|
end
|
281
316
|
|
282
317
|
end
|
data/test/test_byte_buffer.rb
CHANGED
data/test/test_chunk.rb
CHANGED
data/test/test_collection.rb
CHANGED
@@ -1,20 +1,5 @@
|
|
1
|
-
# --
|
2
|
-
# Copyright (C) 2008-2009 10gen Inc.
|
3
|
-
#
|
4
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
-
# you may not use this file except in compliance with the License.
|
6
|
-
# You may obtain a copy of the License at
|
7
|
-
#
|
8
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
-
#
|
10
|
-
# Unless required by applicable law or agreed to in writing, software
|
11
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
-
# See the License for the specific language governing permissions and
|
14
|
-
# limitations under the License.
|
15
|
-
# ++
|
16
|
-
|
17
1
|
require 'test/test_helper'
|
2
|
+
|
18
3
|
class TestCollection < Test::Unit::TestCase
|
19
4
|
@@connection = Connection.new(ENV['MONGO_RUBY_DRIVER_HOST'] || 'localhost', ENV['MONGO_RUBY_DRIVER_PORT'] || Connection::DEFAULT_PORT)
|
20
5
|
@@db = @@connection.db('ruby-mongo-test')
|
@@ -41,11 +26,20 @@ class TestCollection < Test::Unit::TestCase
|
|
41
26
|
assert @coll.pk_factory.is_a?(Object)
|
42
27
|
end
|
43
28
|
|
44
|
-
def
|
29
|
+
def test_valid_names
|
45
30
|
assert_raise InvalidName do
|
46
31
|
@@db["te$t"]
|
47
32
|
end
|
48
33
|
|
34
|
+
assert_raise InvalidName do
|
35
|
+
@@db['$main']
|
36
|
+
end
|
37
|
+
|
38
|
+
assert @@db['$cmd']
|
39
|
+
assert @@db['oplog.$main']
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_collection
|
49
43
|
assert_kind_of Collection, @@db["test"]
|
50
44
|
assert_equal @@db["test"].name(), @@db.collection("test").name()
|
51
45
|
assert_equal @@db["test"].name(), @@db[:test].name()
|