mongo 1.1.5 → 1.3.0
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.md +15 -15
- data/Rakefile +38 -17
- data/docs/FAQ.md +4 -0
- data/docs/HISTORY.md +59 -0
- data/docs/RELEASES.md +33 -0
- data/docs/REPLICA_SETS.md +13 -16
- data/lib/mongo/collection.rb +157 -69
- data/lib/mongo/connection.rb +189 -65
- data/lib/mongo/cursor.rb +43 -29
- data/lib/mongo/db.rb +63 -43
- data/lib/mongo/exceptions.rb +4 -1
- data/lib/mongo/gridfs/grid.rb +1 -1
- data/lib/mongo/gridfs/grid_ext.rb +1 -1
- data/lib/mongo/gridfs/grid_file_system.rb +1 -1
- data/lib/mongo/gridfs/grid_io.rb +89 -8
- data/lib/mongo/gridfs/grid_io_fix.rb +1 -1
- data/lib/mongo/repl_set_connection.rb +72 -20
- data/lib/mongo/test.rb +20 -0
- data/lib/mongo/util/conversions.rb +1 -1
- data/lib/mongo/util/core_ext.rb +11 -1
- data/lib/mongo/util/pool.rb +67 -15
- data/lib/mongo/util/server_version.rb +1 -1
- data/lib/mongo/util/support.rb +1 -1
- data/lib/mongo/util/uri_parser.rb +127 -13
- data/lib/mongo.rb +38 -2
- data/test/async/collection_test.rb +224 -0
- data/test/async/connection_test.rb +24 -0
- data/test/async/cursor_test.rb +162 -0
- data/test/async/worker_pool_test.rb +99 -0
- data/test/auxillary/fork_test.rb +30 -0
- data/test/auxillary/repl_set_auth_test.rb +58 -0
- data/test/auxillary/threaded_authentication_test.rb +101 -0
- data/test/bson/bson_test.rb +140 -28
- data/test/bson/byte_buffer_test.rb +18 -0
- data/test/bson/object_id_test.rb +14 -1
- data/test/bson/ordered_hash_test.rb +7 -0
- data/test/bson/timestamp_test.rb +24 -0
- data/test/collection_test.rb +104 -15
- data/test/connection_test.rb +78 -2
- data/test/conversions_test.rb +10 -11
- data/test/cursor_fail_test.rb +1 -1
- data/test/cursor_message_test.rb +1 -1
- data/test/cursor_test.rb +33 -4
- data/test/db_api_test.rb +30 -52
- data/test/db_test.rb +3 -3
- data/test/grid_file_system_test.rb +0 -1
- data/test/grid_io_test.rb +72 -1
- data/test/grid_test.rb +16 -16
- data/test/load/resque/load.rb +21 -0
- data/test/load/resque/processor.rb +26 -0
- data/test/load/thin/load.rb +24 -0
- data/test/load/unicorn/load.rb +23 -0
- data/test/load/unicorn/unicorn.rb +29 -0
- data/test/replica_sets/connect_test.rb +11 -1
- data/test/replica_sets/connection_string_test.rb +32 -0
- data/test/replica_sets/query_secondaries.rb +16 -0
- data/test/replica_sets/query_test.rb +10 -0
- data/test/replica_sets/replication_ack_test.rb +2 -0
- data/test/replica_sets/rs_test_helper.rb +9 -11
- data/test/support/hash_with_indifferent_access.rb +0 -13
- data/test/support_test.rb +0 -1
- data/test/test_helper.rb +27 -8
- data/test/tools/auth_repl_set_manager.rb +14 -0
- data/test/tools/load.rb +58 -0
- data/test/tools/repl_set_manager.rb +34 -9
- data/test/tools/sharding_manager.rb +202 -0
- data/test/tools/test.rb +3 -12
- data/test/unit/collection_test.rb +20 -24
- data/test/unit/connection_test.rb +4 -18
- data/test/unit/cursor_test.rb +16 -6
- data/test/unit/db_test.rb +10 -11
- data/test/unit/repl_set_connection_test.rb +0 -23
- data/test/unit/safe_test.rb +3 -3
- data/test/uri_test.rb +91 -0
- metadata +49 -12
- data/docs/1.0_UPGRADE.md +0 -21
data/test/bson/bson_test.rb
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
# encoding:utf-8
|
|
2
2
|
require './test/test_helper'
|
|
3
|
-
|
|
3
|
+
|
|
4
|
+
if RUBY_VERSION < '1.9'
|
|
5
|
+
require 'complex'
|
|
6
|
+
require 'rational'
|
|
7
|
+
end
|
|
4
8
|
require 'bigdecimal'
|
|
5
|
-
require 'rational'
|
|
6
9
|
|
|
7
10
|
begin
|
|
11
|
+
require 'tzinfo'
|
|
8
12
|
require 'active_support/core_ext'
|
|
9
13
|
Time.zone = "Pacific Time (US & Canada)"
|
|
10
14
|
Zone = Time.zone.now
|
|
@@ -67,13 +71,26 @@ class BSONTest < Test::Unit::TestCase
|
|
|
67
71
|
assert_doc_pass(doc)
|
|
68
72
|
end
|
|
69
73
|
|
|
70
|
-
def
|
|
71
|
-
doc = {'name' => 'a' *
|
|
74
|
+
def test_limit_max_bson_size
|
|
75
|
+
doc = {'name' => 'a' * BSON_CODER.max_bson_size}
|
|
72
76
|
assert_raise InvalidDocument do
|
|
73
77
|
assert @encoder.serialize(doc)
|
|
74
78
|
end
|
|
75
79
|
end
|
|
76
80
|
|
|
81
|
+
def test_max_bson_size
|
|
82
|
+
assert BSON_CODER.max_bson_size >= BSON::DEFAULT_MAX_BSON_SIZE
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def test_update_max_bson_size
|
|
86
|
+
require 'ostruct'
|
|
87
|
+
mock_conn = OpenStruct.new
|
|
88
|
+
size = 7 * 1024 * 1024
|
|
89
|
+
mock_conn.max_bson_size = size
|
|
90
|
+
assert_equal size, BSON_CODER.update_max_bson_size(mock_conn)
|
|
91
|
+
assert_equal size, BSON_CODER.max_bson_size
|
|
92
|
+
end
|
|
93
|
+
|
|
77
94
|
def test_round_trip
|
|
78
95
|
doc = {'doc' => 123}
|
|
79
96
|
@encoder.deserialize(@encoder.serialize(doc))
|
|
@@ -103,15 +120,23 @@ class BSONTest < Test::Unit::TestCase
|
|
|
103
120
|
end
|
|
104
121
|
else
|
|
105
122
|
def test_non_utf8_string
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
123
|
+
assert_raise BSON::InvalidStringEncoding do
|
|
124
|
+
BSON::BSON_CODER.serialize({'str' => 'aé'.encode('iso-8859-1')})
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
def test_invalid_utf8_string
|
|
129
|
+
str = "123\xD9"
|
|
130
|
+
assert !str.valid_encoding?
|
|
131
|
+
assert_raise BSON::InvalidStringEncoding do
|
|
132
|
+
BSON::BSON_CODER.serialize({'str' => str})
|
|
133
|
+
end
|
|
110
134
|
end
|
|
111
135
|
|
|
112
136
|
def test_non_utf8_key
|
|
113
|
-
|
|
114
|
-
|
|
137
|
+
assert_raise BSON::InvalidStringEncoding do
|
|
138
|
+
BSON::BSON_CODER.serialize({'aé'.encode('iso-8859-1') => 'hello'})
|
|
139
|
+
end
|
|
115
140
|
end
|
|
116
141
|
|
|
117
142
|
# Based on a test from sqlite3-ruby
|
|
@@ -121,14 +146,14 @@ class BSONTest < Test::Unit::TestCase
|
|
|
121
146
|
str = "壁に耳あり、障子に目あり"
|
|
122
147
|
bson = BSON::BSON_CODER.serialize("x" => str)
|
|
123
148
|
|
|
124
|
-
Encoding.default_internal = 'EUC-JP'
|
|
149
|
+
silently { Encoding.default_internal = 'EUC-JP' }
|
|
125
150
|
out = BSON::BSON_CODER.deserialize(bson)["x"]
|
|
126
151
|
|
|
127
152
|
assert_equal Encoding.default_internal, out.encoding
|
|
128
153
|
assert_equal str.encode('EUC-JP'), out
|
|
129
154
|
assert_equal str, out.encode(str.encoding)
|
|
130
155
|
ensure
|
|
131
|
-
Encoding.default_internal = before_enc
|
|
156
|
+
silently { Encoding.default_internal = before_enc }
|
|
132
157
|
end
|
|
133
158
|
end
|
|
134
159
|
|
|
@@ -137,17 +162,23 @@ class BSONTest < Test::Unit::TestCase
|
|
|
137
162
|
assert_doc_pass(doc)
|
|
138
163
|
end
|
|
139
164
|
|
|
165
|
+
def test_code_with_symbol
|
|
166
|
+
assert_raise_error ArgumentError, "BSON::Code must be in the form of a String" do
|
|
167
|
+
Code.new(:fubar)
|
|
168
|
+
end
|
|
169
|
+
end
|
|
170
|
+
|
|
140
171
|
def test_code_with_scope
|
|
141
172
|
doc = {'$where' => Code.new('this.a.b < this.b', {'foo' => 1})}
|
|
142
173
|
assert_doc_pass(doc)
|
|
143
174
|
end
|
|
144
175
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
176
|
+
def test_double
|
|
177
|
+
doc = {'doc' => 41.25}
|
|
178
|
+
assert_doc_pass(doc)
|
|
179
|
+
end
|
|
149
180
|
|
|
150
|
-
|
|
181
|
+
def test_int
|
|
151
182
|
doc = {'doc' => 42}
|
|
152
183
|
assert_doc_pass(doc)
|
|
153
184
|
|
|
@@ -200,6 +231,15 @@ class BSONTest < Test::Unit::TestCase
|
|
|
200
231
|
assert_doc_pass(doc)
|
|
201
232
|
end
|
|
202
233
|
|
|
234
|
+
def test_array_keys
|
|
235
|
+
doc = {'doc' => [1, 2, 'a', 'b']}
|
|
236
|
+
bson = @encoder.serialize(doc).to_a
|
|
237
|
+
assert_equal 48, bson[14]
|
|
238
|
+
assert_equal 49, bson[21]
|
|
239
|
+
assert_equal 50, bson[28]
|
|
240
|
+
assert_equal 51, bson[37]
|
|
241
|
+
end
|
|
242
|
+
|
|
203
243
|
def test_regex
|
|
204
244
|
doc = {'doc' => /foobar/i}
|
|
205
245
|
assert_doc_pass(doc)
|
|
@@ -218,8 +258,14 @@ class BSONTest < Test::Unit::TestCase
|
|
|
218
258
|
assert_in_delta doc['date'], doc2['date'], 0.001
|
|
219
259
|
end
|
|
220
260
|
|
|
261
|
+
def test_date_in_array
|
|
262
|
+
doc = {'date' => [Time.now.utc]}
|
|
263
|
+
bson = @encoder.serialize(doc)
|
|
264
|
+
doc2 = @encoder.deserialize(bson)
|
|
265
|
+
end
|
|
266
|
+
|
|
221
267
|
def test_date_returns_as_utc
|
|
222
|
-
doc = {'date' => Time.now}
|
|
268
|
+
doc = {'date' => Time.now.utc}
|
|
223
269
|
bson = @encoder.serialize(doc)
|
|
224
270
|
doc2 = @encoder.deserialize(bson)
|
|
225
271
|
assert doc2['date'].utc?
|
|
@@ -249,7 +295,7 @@ class BSONTest < Test::Unit::TestCase
|
|
|
249
295
|
ensure
|
|
250
296
|
if !invalid_date.is_a? Time
|
|
251
297
|
assert_equal InvalidDocument, e.class
|
|
252
|
-
assert_match
|
|
298
|
+
assert_match(/UTC Time/, e.message)
|
|
253
299
|
end
|
|
254
300
|
end
|
|
255
301
|
end
|
|
@@ -283,6 +329,20 @@ class BSONTest < Test::Unit::TestCase
|
|
|
283
329
|
bin = Binary.new
|
|
284
330
|
'binstring'.each_byte { |b| bin.put(b) }
|
|
285
331
|
|
|
332
|
+
doc = {'bin' => bin}
|
|
333
|
+
bson = @encoder.serialize(doc)
|
|
334
|
+
doc2 = @encoder.deserialize(bson)
|
|
335
|
+
bin2 = doc2['bin']
|
|
336
|
+
assert_kind_of Binary, bin2
|
|
337
|
+
assert_equal 'binstring', bin2.to_s
|
|
338
|
+
assert_equal Binary::SUBTYPE_SIMPLE, bin2.subtype
|
|
339
|
+
end
|
|
340
|
+
|
|
341
|
+
def test_binary_with_deprecated_subtype
|
|
342
|
+
bin = Binary.new
|
|
343
|
+
'binstring'.each_byte { |b| bin.put(b) }
|
|
344
|
+
bin.subtype = Binary::SUBTYPE_BYTES
|
|
345
|
+
|
|
286
346
|
doc = {'bin' => bin}
|
|
287
347
|
bson = @encoder.serialize(doc)
|
|
288
348
|
doc2 = @encoder.deserialize(bson)
|
|
@@ -300,7 +360,7 @@ class BSONTest < Test::Unit::TestCase
|
|
|
300
360
|
bin2 = doc2['bin']
|
|
301
361
|
assert_kind_of Binary, bin2
|
|
302
362
|
assert_equal 'somebinarystring', bin2.to_s
|
|
303
|
-
assert_equal Binary::
|
|
363
|
+
assert_equal Binary::SUBTYPE_SIMPLE, bin2.subtype
|
|
304
364
|
end
|
|
305
365
|
|
|
306
366
|
def test_binary_type
|
|
@@ -340,7 +400,7 @@ class BSONTest < Test::Unit::TestCase
|
|
|
340
400
|
bin2 = doc2['bin']
|
|
341
401
|
assert_kind_of Binary, bin2
|
|
342
402
|
assert_equal [1, 2, 3, 4, 5], bin2.to_a
|
|
343
|
-
assert_equal Binary::
|
|
403
|
+
assert_equal Binary::SUBTYPE_SIMPLE, bin2.subtype
|
|
344
404
|
end
|
|
345
405
|
|
|
346
406
|
def test_put_id_first
|
|
@@ -365,15 +425,24 @@ class BSONTest < Test::Unit::TestCase
|
|
|
365
425
|
if !(RUBY_PLATFORM =~ /java/)
|
|
366
426
|
def test_timestamp
|
|
367
427
|
val = {"test" => [4, 20]}
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
428
|
+
result = @encoder.deserialize([0x13, 0x00, 0x00, 0x00,
|
|
429
|
+
0x11, 0x74, 0x65, 0x73,
|
|
430
|
+
0x74, 0x00, 0x04, 0x00,
|
|
431
|
+
0x00, 0x00, 0x14, 0x00,
|
|
432
|
+
0x00, 0x00, 0x00])
|
|
433
|
+
|
|
434
|
+
assert_equal 4, result["test"][0]
|
|
435
|
+
assert_equal 20, result["test"][1]
|
|
374
436
|
end
|
|
375
437
|
end
|
|
376
438
|
|
|
439
|
+
def test_timestamp_type
|
|
440
|
+
ts = Timestamp.new(5000, 100)
|
|
441
|
+
doc = {:ts => ts}
|
|
442
|
+
bson = @encoder.serialize(doc)
|
|
443
|
+
assert_equal ts, @encoder.deserialize(bson)["ts"]
|
|
444
|
+
end
|
|
445
|
+
|
|
377
446
|
def test_overflow
|
|
378
447
|
doc = {"x" => 2**75}
|
|
379
448
|
assert_raise RangeError do
|
|
@@ -411,7 +480,7 @@ class BSONTest < Test::Unit::TestCase
|
|
|
411
480
|
rescue => e
|
|
412
481
|
ensure
|
|
413
482
|
assert_equal InvalidDocument, e.class
|
|
414
|
-
assert_match
|
|
483
|
+
assert_match(/Cannot serialize/, e.message)
|
|
415
484
|
end
|
|
416
485
|
end
|
|
417
486
|
end
|
|
@@ -534,4 +603,47 @@ class BSONTest < Test::Unit::TestCase
|
|
|
534
603
|
end
|
|
535
604
|
end
|
|
536
605
|
|
|
606
|
+
def test_invalid_key_names
|
|
607
|
+
assert @encoder.serialize({"hello" => "world"}, true)
|
|
608
|
+
assert @encoder.serialize({"hello" => {"hello" => "world"}}, true)
|
|
609
|
+
|
|
610
|
+
assert @encoder.serialize({"he$llo" => "world"}, true)
|
|
611
|
+
assert @encoder.serialize({"hello" => {"hell$o" => "world"}}, true)
|
|
612
|
+
|
|
613
|
+
assert_raise BSON::InvalidDocument do
|
|
614
|
+
@encoder.serialize({"he\0llo" => "world"}, true)
|
|
615
|
+
end
|
|
616
|
+
|
|
617
|
+
assert_raise BSON::InvalidKeyName do
|
|
618
|
+
@encoder.serialize({"$hello" => "world"}, true)
|
|
619
|
+
end
|
|
620
|
+
|
|
621
|
+
assert_raise BSON::InvalidKeyName do
|
|
622
|
+
@encoder.serialize({"hello" => {"$hello" => "world"}}, true)
|
|
623
|
+
end
|
|
624
|
+
|
|
625
|
+
assert_raise BSON::InvalidKeyName do
|
|
626
|
+
@encoder.serialize({".hello" => "world"}, true)
|
|
627
|
+
end
|
|
628
|
+
|
|
629
|
+
assert_raise BSON::InvalidKeyName do
|
|
630
|
+
@encoder.serialize({"hello" => {".hello" => "world"}}, true)
|
|
631
|
+
end
|
|
632
|
+
|
|
633
|
+
assert_raise BSON::InvalidKeyName do
|
|
634
|
+
@encoder.serialize({"hello." => "world"}, true)
|
|
635
|
+
end
|
|
636
|
+
|
|
637
|
+
assert_raise BSON::InvalidKeyName do
|
|
638
|
+
@encoder.serialize({"hello" => {"hello." => "world"}}, true)
|
|
639
|
+
end
|
|
640
|
+
|
|
641
|
+
assert_raise BSON::InvalidKeyName do
|
|
642
|
+
@encoder.serialize({"hel.lo" => "world"}, true)
|
|
643
|
+
end
|
|
644
|
+
|
|
645
|
+
assert_raise BSON::InvalidKeyName do
|
|
646
|
+
@encoder.serialize({"hello" => {"hel.lo" => "world"}}, true)
|
|
647
|
+
end
|
|
648
|
+
end
|
|
537
649
|
end
|
|
@@ -21,6 +21,13 @@ class ByteBufferTest < Test::Unit::TestCase
|
|
|
21
21
|
assert_equal 1, @buf.get
|
|
22
22
|
end
|
|
23
23
|
|
|
24
|
+
def test_unpack
|
|
25
|
+
@buf.put_array([17, 2, 3, 4])
|
|
26
|
+
assert_equal [17, 2, 3, 4], @buf.to_a
|
|
27
|
+
assert_equal ["11020304"], @buf.unpack("H*")
|
|
28
|
+
assert_equal ["11020304"], @buf.to_a("H*")
|
|
29
|
+
end
|
|
30
|
+
|
|
24
31
|
def test_one_get_returns_array_length_one
|
|
25
32
|
@buf.put_array([1, 2, 3, 4])
|
|
26
33
|
@buf.rewind
|
|
@@ -186,5 +193,16 @@ class ByteBufferTest < Test::Unit::TestCase
|
|
|
186
193
|
@buf.get_int
|
|
187
194
|
assert !@buf.more?
|
|
188
195
|
end
|
|
196
|
+
|
|
197
|
+
def test_equality
|
|
198
|
+
@buf = ByteBuffer.new("foo")
|
|
199
|
+
assert_equal @buf, @buf
|
|
200
|
+
assert_equal ByteBuffer.new(""), ByteBuffer.new("")
|
|
201
|
+
assert_equal ByteBuffer.new("123"), ByteBuffer.new("123")
|
|
202
|
+
assert_not_equal ByteBuffer.new("123"), ByteBuffer.new("1234")
|
|
203
|
+
assert_equal @buf, "foo"
|
|
204
|
+
assert_not_equal @buf, 123
|
|
205
|
+
assert_not_equal @buf, nil
|
|
206
|
+
end
|
|
189
207
|
|
|
190
208
|
end
|
data/test/bson/object_id_test.rb
CHANGED
|
@@ -126,14 +126,27 @@ class ObjectIdTest < Test::Unit::TestCase
|
|
|
126
126
|
time = Time.now.utc
|
|
127
127
|
id = ObjectId.from_time(time)
|
|
128
128
|
|
|
129
|
+
assert id.to_a[4, 8].all? {|byte| byte == 0 }
|
|
129
130
|
assert_equal time.to_i, id.generation_time.to_i
|
|
130
131
|
end
|
|
131
132
|
|
|
133
|
+
def test_from_time_unique
|
|
134
|
+
time = Time.now.utc
|
|
135
|
+
id = ObjectId.from_time(time, :unique => true)
|
|
136
|
+
|
|
137
|
+
mac_id = Digest::MD5.digest(Socket.gethostname)[0, 3].unpack("C3")
|
|
138
|
+
assert_equal id.to_a[4, 3], mac_id
|
|
139
|
+
assert_equal time.to_i, id.generation_time.to_i
|
|
140
|
+
|
|
141
|
+
id2 = ObjectId.new(nil, time)
|
|
142
|
+
assert_equal time.to_i, id2.generation_time.to_i
|
|
143
|
+
end
|
|
144
|
+
|
|
132
145
|
def test_json
|
|
133
146
|
id = ObjectId.new
|
|
134
147
|
assert_equal "{\"$oid\": \"#{id}\"}", id.to_json
|
|
135
148
|
end
|
|
136
|
-
|
|
149
|
+
|
|
137
150
|
def test_as_json
|
|
138
151
|
id = ObjectId.new
|
|
139
152
|
assert_equal({"$oid" => id.to_s}, id.as_json)
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
require './test/test_helper'
|
|
2
|
+
|
|
3
|
+
class TiumestampTest < Test::Unit::TestCase
|
|
4
|
+
include Mongo
|
|
5
|
+
|
|
6
|
+
def test_timestamp_equality
|
|
7
|
+
t1 = Timestamp.new(5000, 200)
|
|
8
|
+
t2 = Timestamp.new(5000, 200)
|
|
9
|
+
assert_equal t2, t1
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def test_implements_array_for_backward_compatibility
|
|
13
|
+
ts = Timestamp.new(5000, 200)
|
|
14
|
+
assert_equal 200, ts[0]
|
|
15
|
+
assert_equal 5000, ts[1]
|
|
16
|
+
|
|
17
|
+
array = ts.map {|t| t }
|
|
18
|
+
assert_equal 2, array.length
|
|
19
|
+
|
|
20
|
+
assert_equal 200, array[0]
|
|
21
|
+
assert_equal 5000, array[1]
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
end
|
data/test/collection_test.rb
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
require './test/test_helper'
|
|
2
2
|
|
|
3
3
|
class TestCollection < Test::Unit::TestCase
|
|
4
|
-
@@connection ||= standard_connection
|
|
4
|
+
@@connection ||= standard_connection(:op_timeout => 2)
|
|
5
5
|
@@db = @@connection.db(MONGO_TEST_DB)
|
|
6
6
|
@@test = @@db.collection("test")
|
|
7
7
|
@@version = @@connection.server_version
|
|
@@ -32,11 +32,11 @@ class TestCollection < Test::Unit::TestCase
|
|
|
32
32
|
end
|
|
33
33
|
|
|
34
34
|
def test_pk_factory_on_collection
|
|
35
|
-
@coll = Collection.new(
|
|
35
|
+
@coll = Collection.new('foo', @@db, TestPK)
|
|
36
36
|
assert_equal TestPK, @coll.pk_factory
|
|
37
37
|
|
|
38
38
|
|
|
39
|
-
@coll2 = Collection.new(
|
|
39
|
+
@coll2 = Collection.new('foo', @@db, :pk => TestPK)
|
|
40
40
|
assert_equal TestPK, @coll2.pk_factory
|
|
41
41
|
end
|
|
42
42
|
|
|
@@ -373,8 +373,8 @@ class TestCollection < Test::Unit::TestCase
|
|
|
373
373
|
|
|
374
374
|
docs = [{"hello" => "world"}, {"hello" => "world"}]
|
|
375
375
|
@@test.insert(docs)
|
|
376
|
-
docs.each do |
|
|
377
|
-
assert(
|
|
376
|
+
docs.each do |d|
|
|
377
|
+
assert(d.include?(:_id))
|
|
378
378
|
end
|
|
379
379
|
end
|
|
380
380
|
|
|
@@ -417,7 +417,7 @@ class TestCollection < Test::Unit::TestCase
|
|
|
417
417
|
|
|
418
418
|
m = "function() { emit(this.user_id, 1); }"
|
|
419
419
|
r = "function(k,vals) { return 1; }"
|
|
420
|
-
res = @@test.map_reduce(m, r);
|
|
420
|
+
res = @@test.map_reduce(m, r, :out => 'foo');
|
|
421
421
|
assert res.find_one({"_id" => 1})
|
|
422
422
|
assert res.find_one({"_id" => 2})
|
|
423
423
|
end
|
|
@@ -428,7 +428,7 @@ class TestCollection < Test::Unit::TestCase
|
|
|
428
428
|
|
|
429
429
|
m = Code.new("function() { emit(this.user_id, 1); }")
|
|
430
430
|
r = Code.new("function(k,vals) { return 1; }")
|
|
431
|
-
res = @@test.map_reduce(m, r);
|
|
431
|
+
res = @@test.map_reduce(m, r, :out => 'foo');
|
|
432
432
|
assert res.find_one({"_id" => 1})
|
|
433
433
|
assert res.find_one({"_id" => 2})
|
|
434
434
|
end
|
|
@@ -441,7 +441,7 @@ class TestCollection < Test::Unit::TestCase
|
|
|
441
441
|
|
|
442
442
|
m = Code.new("function() { emit(this.user_id, 1); }")
|
|
443
443
|
r = Code.new("function(k,vals) { return 1; }")
|
|
444
|
-
res = @@test.map_reduce(m, r, :query => {"user_id" => {"$gt" => 1}});
|
|
444
|
+
res = @@test.map_reduce(m, r, :query => {"user_id" => {"$gt" => 1}}, :out => 'foo');
|
|
445
445
|
assert_equal 2, res.count
|
|
446
446
|
assert res.find_one({"_id" => 2})
|
|
447
447
|
assert res.find_one({"_id" => 3})
|
|
@@ -450,7 +450,7 @@ class TestCollection < Test::Unit::TestCase
|
|
|
450
450
|
def test_map_reduce_with_raw_response
|
|
451
451
|
m = Code.new("function() { emit(this.user_id, 1); }")
|
|
452
452
|
r = Code.new("function(k,vals) { return 1; }")
|
|
453
|
-
res = @@test.map_reduce(m, r, :raw => true)
|
|
453
|
+
res = @@test.map_reduce(m, r, :raw => true, :out => 'foo')
|
|
454
454
|
assert res["result"]
|
|
455
455
|
assert res["counts"]
|
|
456
456
|
assert res["timeMillis"]
|
|
@@ -465,6 +465,36 @@ class TestCollection < Test::Unit::TestCase
|
|
|
465
465
|
assert res["counts"]
|
|
466
466
|
assert res["timeMillis"]
|
|
467
467
|
end
|
|
468
|
+
|
|
469
|
+
|
|
470
|
+
if @@version >= "1.8.0"
|
|
471
|
+
def test_map_reduce_with_collection_merge
|
|
472
|
+
@@test << {:user_id => 1}
|
|
473
|
+
@@test << {:user_id => 2}
|
|
474
|
+
output_collection = "test-map-coll"
|
|
475
|
+
m = Code.new("function() { emit(this.user_id, {count: 1}); }")
|
|
476
|
+
r = Code.new("function(k,vals) { var sum = 0;" +
|
|
477
|
+
" vals.forEach(function(v) { sum += v.count;} ); return {count: sum}; }")
|
|
478
|
+
res = @@test.map_reduce(m, r, :out => output_collection)
|
|
479
|
+
|
|
480
|
+
@@test.remove
|
|
481
|
+
@@test << {:user_id => 3}
|
|
482
|
+
res = @@test.map_reduce(m, r, :out => {:merge => output_collection})
|
|
483
|
+
assert res.find.to_a.any? {|doc| doc["_id"] == 3 && doc["value"]["count"] == 1}
|
|
484
|
+
|
|
485
|
+
@@test.remove
|
|
486
|
+
@@test << {:user_id => 3}
|
|
487
|
+
res = @@test.map_reduce(m, r, :out => {:reduce => output_collection})
|
|
488
|
+
assert res.find.to_a.any? {|doc| doc["_id"] == 3 && doc["value"]["count"] == 2}
|
|
489
|
+
|
|
490
|
+
assert_raise ArgumentError do
|
|
491
|
+
@@test.map_reduce(m, r, :out => {:inline => 1})
|
|
492
|
+
end
|
|
493
|
+
|
|
494
|
+
@@test.map_reduce(m, r, :raw => true, :out => {:inline => 1})
|
|
495
|
+
assert res["results"]
|
|
496
|
+
end
|
|
497
|
+
end
|
|
468
498
|
end
|
|
469
499
|
|
|
470
500
|
if @@version > "1.3.0"
|
|
@@ -565,6 +595,20 @@ class TestCollection < Test::Unit::TestCase
|
|
|
565
595
|
assert_equal 1, x
|
|
566
596
|
end
|
|
567
597
|
|
|
598
|
+
def test_find_with_transformer
|
|
599
|
+
klass = Struct.new(:id, :a)
|
|
600
|
+
transformer = Proc.new { |doc| klass.new(doc['_id'], doc['a']) }
|
|
601
|
+
cursor = @@test.find({}, :transformer => transformer)
|
|
602
|
+
assert_equal(transformer, cursor.transformer)
|
|
603
|
+
end
|
|
604
|
+
|
|
605
|
+
def test_find_one_with_transformer
|
|
606
|
+
klass = Struct.new(:id, :a)
|
|
607
|
+
transformer = Proc.new { |doc| klass.new(doc['_id'], doc['a']) }
|
|
608
|
+
id = @@test.insert('a' => 1)
|
|
609
|
+
doc = @@test.find_one(id, :transformer => transformer)
|
|
610
|
+
assert_instance_of(klass, doc)
|
|
611
|
+
end
|
|
568
612
|
|
|
569
613
|
def test_ensure_index
|
|
570
614
|
@@test.drop_indexes
|
|
@@ -600,6 +644,23 @@ class TestCollection < Test::Unit::TestCase
|
|
|
600
644
|
@@test.drop_index("a_1")
|
|
601
645
|
end
|
|
602
646
|
|
|
647
|
+
def test_ensure_index_timeout
|
|
648
|
+
@@db.cache_time = 2
|
|
649
|
+
coll = @@db['ensure_test']
|
|
650
|
+
coll.expects(:generate_indexes).twice
|
|
651
|
+
coll.ensure_index([['a', 1]])
|
|
652
|
+
|
|
653
|
+
# These will be cached
|
|
654
|
+
coll.ensure_index([['a', 1]])
|
|
655
|
+
coll.ensure_index([['a', 1]])
|
|
656
|
+
coll.ensure_index([['a', 1]])
|
|
657
|
+
coll.ensure_index([['a', 1]])
|
|
658
|
+
|
|
659
|
+
sleep(3)
|
|
660
|
+
# This won't be, so generate_indexes will be called twice
|
|
661
|
+
coll.ensure_index([['a', 1]])
|
|
662
|
+
end
|
|
663
|
+
|
|
603
664
|
context "Grouping" do
|
|
604
665
|
setup do
|
|
605
666
|
@@test.remove
|
|
@@ -609,15 +670,25 @@ class TestCollection < Test::Unit::TestCase
|
|
|
609
670
|
@reduce_function = "function (obj, prev) { prev.count += inc_value; }"
|
|
610
671
|
end
|
|
611
672
|
|
|
673
|
+
should "fail if missing required options" do
|
|
674
|
+
assert_raise MongoArgumentError do
|
|
675
|
+
@@test.group(:initial => {})
|
|
676
|
+
end
|
|
677
|
+
|
|
678
|
+
assert_raise MongoArgumentError do
|
|
679
|
+
@@test.group(:reduce => "foo")
|
|
680
|
+
end
|
|
681
|
+
end
|
|
682
|
+
|
|
612
683
|
should "group results using eval form" do
|
|
613
|
-
assert_equal 1, @@test.group(
|
|
614
|
-
assert_equal 2, @@test.group(
|
|
615
|
-
assert_equal 4, @@test.group(
|
|
684
|
+
assert_equal 1, @@test.group(:initial => @initial, :reduce => Code.new(@reduce_function, {"inc_value" => 0.5}))[0]["count"]
|
|
685
|
+
assert_equal 2, @@test.group(:initial => @initial, :reduce => Code.new(@reduce_function, {"inc_value" => 1}))[0]["count"]
|
|
686
|
+
assert_equal 4, @@test.group(:initial => @initial, :reduce => Code.new(@reduce_function, {"inc_value" => 2}))[0]["count"]
|
|
616
687
|
end
|
|
617
688
|
|
|
618
689
|
should "finalize grouped results" do
|
|
619
690
|
@finalize = "function(doc) {doc.f = doc.count + 200; }"
|
|
620
|
-
assert_equal 202, @@test.group(
|
|
691
|
+
assert_equal 202, @@test.group(:initial => @initial, :reduce => Code.new(@reduce_function, {"inc_value" => 1}), :finalize => @finalize)[0]["f"]
|
|
621
692
|
end
|
|
622
693
|
end
|
|
623
694
|
|
|
@@ -633,7 +704,7 @@ class TestCollection < Test::Unit::TestCase
|
|
|
633
704
|
end
|
|
634
705
|
|
|
635
706
|
should "group" do
|
|
636
|
-
result = @@test.group(
|
|
707
|
+
result = @@test.group(:key => :a, :initial => @initial, :reduce => @reduce_function)
|
|
637
708
|
assert result.all? { |r| r['count'] == 200 }
|
|
638
709
|
end
|
|
639
710
|
end
|
|
@@ -652,10 +723,17 @@ class TestCollection < Test::Unit::TestCase
|
|
|
652
723
|
end
|
|
653
724
|
|
|
654
725
|
should "group results" do
|
|
655
|
-
results = @@test.group(@keyf,
|
|
726
|
+
results = @@test.group(:keyf => @keyf, :initial => @initial, :reduce => @reduce).sort {|a, b| a['count'] <=> b['count']}
|
|
656
727
|
assert results[0]['even'] && results[0]['count'] == 2.0
|
|
657
728
|
assert results[1]['odd'] && results[1]['count'] == 3.0
|
|
658
729
|
end
|
|
730
|
+
|
|
731
|
+
should "group filtered results" do
|
|
732
|
+
results = @@test.group(:keyf => @keyf, :cond => {:a => {'$ne' => 2}},
|
|
733
|
+
:initial => @initial, :reduce => @reduce).sort {|a, b| a['count'] <=> b['count']}
|
|
734
|
+
assert results[0]['even'] && results[0]['count'] == 1.0
|
|
735
|
+
assert results[1]['odd'] && results[1]['count'] == 3.0
|
|
736
|
+
end
|
|
659
737
|
end
|
|
660
738
|
|
|
661
739
|
context "A collection with two records" do
|
|
@@ -693,6 +771,17 @@ class TestCollection < Test::Unit::TestCase
|
|
|
693
771
|
@geo = @@db.collection('geo')
|
|
694
772
|
end
|
|
695
773
|
|
|
774
|
+
should "create index using symbols" do
|
|
775
|
+
@collection.create_index :foo, :name => :bar
|
|
776
|
+
@geo.create_index :goo, :name => :baz
|
|
777
|
+
assert @collection.index_information['bar']
|
|
778
|
+
@collection.drop_index :bar
|
|
779
|
+
assert_nil @collection.index_information['bar']
|
|
780
|
+
assert @geo.index_information['baz']
|
|
781
|
+
@geo.drop_index(:baz)
|
|
782
|
+
assert_nil @geo.index_information['baz']
|
|
783
|
+
end
|
|
784
|
+
|
|
696
785
|
should "create a geospatial index" do
|
|
697
786
|
@geo.save({'loc' => [-100, 100]})
|
|
698
787
|
@geo.create_index([['loc', Mongo::GEO2D]])
|