mongo-lyon 1.2.4

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.
Files changed (87) hide show
  1. data/LICENSE.txt +190 -0
  2. data/README.md +344 -0
  3. data/Rakefile +202 -0
  4. data/bin/mongo_console +34 -0
  5. data/docs/1.0_UPGRADE.md +21 -0
  6. data/docs/CREDITS.md +123 -0
  7. data/docs/FAQ.md +116 -0
  8. data/docs/GridFS.md +158 -0
  9. data/docs/HISTORY.md +225 -0
  10. data/docs/REPLICA_SETS.md +72 -0
  11. data/docs/TUTORIAL.md +247 -0
  12. data/docs/WRITE_CONCERN.md +28 -0
  13. data/lib/mongo.rb +77 -0
  14. data/lib/mongo/collection.rb +872 -0
  15. data/lib/mongo/connection.rb +875 -0
  16. data/lib/mongo/cursor.rb +449 -0
  17. data/lib/mongo/db.rb +607 -0
  18. data/lib/mongo/exceptions.rb +68 -0
  19. data/lib/mongo/gridfs/grid.rb +106 -0
  20. data/lib/mongo/gridfs/grid_ext.rb +57 -0
  21. data/lib/mongo/gridfs/grid_file_system.rb +145 -0
  22. data/lib/mongo/gridfs/grid_io.rb +394 -0
  23. data/lib/mongo/gridfs/grid_io_fix.rb +38 -0
  24. data/lib/mongo/repl_set_connection.rb +342 -0
  25. data/lib/mongo/util/conversions.rb +89 -0
  26. data/lib/mongo/util/core_ext.rb +60 -0
  27. data/lib/mongo/util/pool.rb +185 -0
  28. data/lib/mongo/util/server_version.rb +71 -0
  29. data/lib/mongo/util/support.rb +82 -0
  30. data/lib/mongo/util/uri_parser.rb +181 -0
  31. data/lib/mongo/version.rb +3 -0
  32. data/mongo.gemspec +34 -0
  33. data/test/auxillary/1.4_features.rb +166 -0
  34. data/test/auxillary/authentication_test.rb +68 -0
  35. data/test/auxillary/autoreconnect_test.rb +41 -0
  36. data/test/auxillary/repl_set_auth_test.rb +58 -0
  37. data/test/auxillary/slave_connection_test.rb +36 -0
  38. data/test/auxillary/threaded_authentication_test.rb +101 -0
  39. data/test/bson/binary_test.rb +15 -0
  40. data/test/bson/bson_test.rb +614 -0
  41. data/test/bson/byte_buffer_test.rb +190 -0
  42. data/test/bson/hash_with_indifferent_access_test.rb +38 -0
  43. data/test/bson/json_test.rb +17 -0
  44. data/test/bson/object_id_test.rb +154 -0
  45. data/test/bson/ordered_hash_test.rb +197 -0
  46. data/test/collection_test.rb +893 -0
  47. data/test/connection_test.rb +303 -0
  48. data/test/conversions_test.rb +120 -0
  49. data/test/cursor_fail_test.rb +75 -0
  50. data/test/cursor_message_test.rb +43 -0
  51. data/test/cursor_test.rb +457 -0
  52. data/test/db_api_test.rb +715 -0
  53. data/test/db_connection_test.rb +15 -0
  54. data/test/db_test.rb +287 -0
  55. data/test/grid_file_system_test.rb +244 -0
  56. data/test/grid_io_test.rb +120 -0
  57. data/test/grid_test.rb +200 -0
  58. data/test/load/thin/load.rb +24 -0
  59. data/test/load/unicorn/load.rb +23 -0
  60. data/test/replica_sets/connect_test.rb +86 -0
  61. data/test/replica_sets/connection_string_test.rb +32 -0
  62. data/test/replica_sets/count_test.rb +35 -0
  63. data/test/replica_sets/insert_test.rb +53 -0
  64. data/test/replica_sets/pooled_insert_test.rb +55 -0
  65. data/test/replica_sets/query_secondaries.rb +96 -0
  66. data/test/replica_sets/query_test.rb +51 -0
  67. data/test/replica_sets/replication_ack_test.rb +66 -0
  68. data/test/replica_sets/rs_test_helper.rb +27 -0
  69. data/test/safe_test.rb +68 -0
  70. data/test/support/hash_with_indifferent_access.rb +199 -0
  71. data/test/support/keys.rb +45 -0
  72. data/test/support_test.rb +19 -0
  73. data/test/test_helper.rb +83 -0
  74. data/test/threading/threading_with_large_pool_test.rb +90 -0
  75. data/test/threading_test.rb +87 -0
  76. data/test/tools/auth_repl_set_manager.rb +14 -0
  77. data/test/tools/repl_set_manager.rb +266 -0
  78. data/test/unit/collection_test.rb +130 -0
  79. data/test/unit/connection_test.rb +98 -0
  80. data/test/unit/cursor_test.rb +99 -0
  81. data/test/unit/db_test.rb +96 -0
  82. data/test/unit/grid_test.rb +49 -0
  83. data/test/unit/pool_test.rb +9 -0
  84. data/test/unit/repl_set_connection_test.rb +72 -0
  85. data/test/unit/safe_test.rb +125 -0
  86. data/test/uri_test.rb +91 -0
  87. metadata +202 -0
@@ -0,0 +1,715 @@
1
+ require './test/test_helper'
2
+
3
+ class DBAPITest < Test::Unit::TestCase
4
+ include Mongo
5
+ include BSON
6
+
7
+ @@conn = standard_connection
8
+ @@db = @@conn.db(MONGO_TEST_DB)
9
+ @@coll = @@db.collection('test')
10
+ @@version = @@conn.server_version
11
+
12
+ def setup
13
+ @@coll.remove
14
+ @r1 = {'a' => 1}
15
+ @@coll.insert(@r1) # collection not created until it's used
16
+ @@coll_full_name = "#{MONGO_TEST_DB}.test"
17
+ end
18
+
19
+ def teardown
20
+ @@coll.remove
21
+ @@db.get_last_error
22
+ end
23
+
24
+ def test_clear
25
+ assert_equal 1, @@coll.count
26
+ @@coll.remove
27
+ assert_equal 0, @@coll.count
28
+ end
29
+
30
+ def test_insert
31
+ assert_kind_of BSON::ObjectId, @@coll.insert('a' => 2)
32
+ assert_kind_of BSON::ObjectId, @@coll.insert('b' => 3)
33
+
34
+ assert_equal 3, @@coll.count
35
+ docs = @@coll.find().to_a
36
+ assert_equal 3, docs.length
37
+ assert docs.detect { |row| row['a'] == 1 }
38
+ assert docs.detect { |row| row['a'] == 2 }
39
+ assert docs.detect { |row| row['b'] == 3 }
40
+
41
+ @@coll << {'b' => 4}
42
+ docs = @@coll.find().to_a
43
+ assert_equal 4, docs.length
44
+ assert docs.detect { |row| row['b'] == 4 }
45
+ end
46
+
47
+ def test_save_ordered_hash
48
+ oh = BSON::OrderedHash.new
49
+ oh['a'] = -1
50
+ oh['b'] = 'foo'
51
+
52
+ oid = @@coll.save(oh)
53
+ assert_equal 'foo', @@coll.find_one(oid)['b']
54
+
55
+ oh = BSON::OrderedHash['a' => 1, 'b' => 'foo']
56
+ oid = @@coll.save(oh)
57
+ assert_equal 'foo', @@coll.find_one(oid)['b']
58
+ end
59
+
60
+ def test_insert_multiple
61
+ ids = @@coll.insert([{'a' => 2}, {'b' => 3}])
62
+
63
+ ids.each do |i|
64
+ assert_kind_of BSON::ObjectId, i
65
+ end
66
+
67
+ assert_equal 3, @@coll.count
68
+ docs = @@coll.find().to_a
69
+ assert_equal 3, docs.length
70
+ assert docs.detect { |row| row['a'] == 1 }
71
+ assert docs.detect { |row| row['a'] == 2 }
72
+ assert docs.detect { |row| row['b'] == 3 }
73
+ end
74
+
75
+ def test_count_on_nonexisting
76
+ @@db.drop_collection('foo')
77
+ assert_equal 0, @@db.collection('foo').count()
78
+ end
79
+
80
+ def test_find_simple
81
+ @r2 = @@coll.insert('a' => 2)
82
+ @r3 = @@coll.insert('b' => 3)
83
+ # Check sizes
84
+ docs = @@coll.find().to_a
85
+ assert_equal 3, docs.size
86
+ assert_equal 3, @@coll.count
87
+
88
+ # Find by other value
89
+ docs = @@coll.find('a' => @r1['a']).to_a
90
+ assert_equal 1, docs.size
91
+ doc = docs.first
92
+ # Can't compare _id values because at insert, an _id was added to @r1 by
93
+ # the database but we don't know what it is without re-reading the record
94
+ # (which is what we are doing right now).
95
+ # assert_equal doc['_id'], @r1['_id']
96
+ assert_equal doc['a'], @r1['a']
97
+ end
98
+
99
+ def test_find_advanced
100
+ @@coll.insert('a' => 2)
101
+ @@coll.insert('b' => 3)
102
+
103
+ # Find by advanced query (less than)
104
+ docs = @@coll.find('a' => { '$lt' => 10 }).to_a
105
+ assert_equal 2, docs.size
106
+ assert docs.detect { |row| row['a'] == 1 }
107
+ assert docs.detect { |row| row['a'] == 2 }
108
+
109
+ # Find by advanced query (greater than)
110
+ docs = @@coll.find('a' => { '$gt' => 1 }).to_a
111
+ assert_equal 1, docs.size
112
+ assert docs.detect { |row| row['a'] == 2 }
113
+
114
+ # Find by advanced query (less than or equal to)
115
+ docs = @@coll.find('a' => { '$lte' => 1 }).to_a
116
+ assert_equal 1, docs.size
117
+ assert docs.detect { |row| row['a'] == 1 }
118
+
119
+ # Find by advanced query (greater than or equal to)
120
+ docs = @@coll.find('a' => { '$gte' => 1 }).to_a
121
+ assert_equal 2, docs.size
122
+ assert docs.detect { |row| row['a'] == 1 }
123
+ assert docs.detect { |row| row['a'] == 2 }
124
+
125
+ # Find by advanced query (between)
126
+ docs = @@coll.find('a' => { '$gt' => 1, '$lt' => 3 }).to_a
127
+ assert_equal 1, docs.size
128
+ assert docs.detect { |row| row['a'] == 2 }
129
+
130
+ # Find by advanced query (in clause)
131
+ docs = @@coll.find('a' => {'$in' => [1,2]}).to_a
132
+ assert_equal 2, docs.size
133
+ assert docs.detect { |row| row['a'] == 1 }
134
+ assert docs.detect { |row| row['a'] == 2 }
135
+ end
136
+
137
+ def test_find_sorting
138
+ @@coll.remove
139
+ @@coll.insert('a' => 1, 'b' => 2)
140
+ @@coll.insert('a' => 2, 'b' => 1)
141
+ @@coll.insert('a' => 3, 'b' => 2)
142
+ @@coll.insert('a' => 4, 'b' => 1)
143
+
144
+ # Sorting (ascending)
145
+ docs = @@coll.find({'a' => { '$lt' => 10 }}, :sort => [['a', 1]]).to_a
146
+ assert_equal 4, docs.size
147
+ assert_equal 1, docs[0]['a']
148
+ assert_equal 2, docs[1]['a']
149
+ assert_equal 3, docs[2]['a']
150
+ assert_equal 4, docs[3]['a']
151
+
152
+ # Sorting (descending)
153
+ docs = @@coll.find({'a' => { '$lt' => 10 }}, :sort => [['a', -1]]).to_a
154
+ assert_equal 4, docs.size
155
+ assert_equal 4, docs[0]['a']
156
+ assert_equal 3, docs[1]['a']
157
+ assert_equal 2, docs[2]['a']
158
+ assert_equal 1, docs[3]['a']
159
+
160
+ # Sorting using array of names; assumes ascending order.
161
+ docs = @@coll.find({'a' => { '$lt' => 10 }}, :sort => 'a').to_a
162
+ assert_equal 4, docs.size
163
+ assert_equal 1, docs[0]['a']
164
+ assert_equal 2, docs[1]['a']
165
+ assert_equal 3, docs[2]['a']
166
+ assert_equal 4, docs[3]['a']
167
+
168
+ # Sorting using single name; assumes ascending order.
169
+ docs = @@coll.find({'a' => { '$lt' => 10 }}, :sort => 'a').to_a
170
+ assert_equal 4, docs.size
171
+ assert_equal 1, docs[0]['a']
172
+ assert_equal 2, docs[1]['a']
173
+ assert_equal 3, docs[2]['a']
174
+ assert_equal 4, docs[3]['a']
175
+
176
+ docs = @@coll.find({'a' => { '$lt' => 10 }}, :sort => [['b', 'asc'], ['a', 'asc']]).to_a
177
+ assert_equal 4, docs.size
178
+ assert_equal 2, docs[0]['a']
179
+ assert_equal 4, docs[1]['a']
180
+ assert_equal 1, docs[2]['a']
181
+ assert_equal 3, docs[3]['a']
182
+
183
+ # Sorting using empty array; no order guarantee should not blow up.
184
+ docs = @@coll.find({'a' => { '$lt' => 10 }}, :sort => []).to_a
185
+ assert_equal 4, docs.size
186
+
187
+ # Sorting using ordered hash. You can use an unordered one, but then the
188
+ # order of the keys won't be guaranteed thus your sort won't make sense.
189
+ oh = BSON::OrderedHash.new
190
+ oh['a'] = -1
191
+ assert_raise InvalidSortValueError do
192
+ docs = @@coll.find({'a' => { '$lt' => 10 }}, :sort => oh).to_a
193
+ end
194
+ end
195
+
196
+ def test_find_limits
197
+ @@coll.insert('b' => 2)
198
+ @@coll.insert('c' => 3)
199
+ @@coll.insert('d' => 4)
200
+
201
+ docs = @@coll.find({}, :limit => 1).to_a
202
+ assert_equal 1, docs.size
203
+ docs = @@coll.find({}, :limit => 2).to_a
204
+ assert_equal 2, docs.size
205
+ docs = @@coll.find({}, :limit => 3).to_a
206
+ assert_equal 3, docs.size
207
+ docs = @@coll.find({}, :limit => 4).to_a
208
+ assert_equal 4, docs.size
209
+ docs = @@coll.find({}).to_a
210
+ assert_equal 4, docs.size
211
+ docs = @@coll.find({}, :limit => 99).to_a
212
+ assert_equal 4, docs.size
213
+ end
214
+
215
+ def test_find_one_no_records
216
+ @@coll.remove
217
+ x = @@coll.find_one('a' => 1)
218
+ assert_nil x
219
+ end
220
+
221
+ def test_drop_collection
222
+ assert @@db.drop_collection(@@coll.name), "drop of collection #{@@coll.name} failed"
223
+ assert !@@db.collection_names.include?(@@coll.name)
224
+ end
225
+
226
+ def test_other_drop
227
+ assert @@db.collection_names.include?(@@coll.name)
228
+ @@coll.drop
229
+ assert !@@db.collection_names.include?(@@coll.name)
230
+ end
231
+
232
+ def test_collection_names
233
+ names = @@db.collection_names
234
+ assert names.length >= 1
235
+ assert names.include?(@@coll.name)
236
+
237
+ coll2 = @@db.collection('test2')
238
+ coll2.insert('a' => 1) # collection not created until it's used
239
+ names = @@db.collection_names
240
+ assert names.length >= 2
241
+ assert names.include?(@@coll.name)
242
+ assert names.include?('mongo-ruby-test.test2')
243
+ ensure
244
+ @@db.drop_collection('test2')
245
+ end
246
+
247
+ def test_collections_info
248
+ cursor = @@db.collections_info
249
+ rows = cursor.to_a
250
+ assert rows.length >= 1
251
+ row = rows.detect { |r| r['name'] == @@coll_full_name }
252
+ assert_not_nil row
253
+ end
254
+
255
+ def test_collection_options
256
+ @@db.drop_collection('foobar')
257
+ @@db.strict = true
258
+
259
+ begin
260
+ coll = @@db.create_collection('foobar', :capped => true, :size => 1024)
261
+ options = coll.options()
262
+ assert_equal 'foobar', options['create']
263
+ assert_equal true, options['capped']
264
+ assert_equal 1024, options['size']
265
+ rescue => ex
266
+ @@db.drop_collection('foobar')
267
+ fail "did not expect exception \"#{ex}\""
268
+ ensure
269
+ @@db.strict = false
270
+ end
271
+ end
272
+
273
+ def test_index_information
274
+ assert_equal @@coll.index_information.length, 1
275
+
276
+ name = @@coll.create_index('a')
277
+ info = @@db.index_information(@@coll.name)
278
+ assert_equal name, "a_1"
279
+ assert_equal @@coll.index_information, info
280
+ assert_equal 2, info.length
281
+
282
+ assert info.has_key?(name)
283
+ assert_equal info[name]["key"], {"a" => 1}
284
+ ensure
285
+ @@db.drop_index(@@coll.name, name)
286
+ end
287
+
288
+ def test_index_create_with_symbol
289
+ assert_equal @@coll.index_information.length, 1
290
+
291
+ name = @@coll.create_index([['a', 1]])
292
+ info = @@db.index_information(@@coll.name)
293
+ assert_equal name, "a_1"
294
+ assert_equal @@coll.index_information, info
295
+ assert_equal 2, info.length
296
+
297
+ assert info.has_key?(name)
298
+ assert_equal info[name]['key'], {"a" => 1}
299
+ ensure
300
+ @@db.drop_index(@@coll.name, name)
301
+ end
302
+
303
+ def test_multiple_index_cols
304
+ name = @@coll.create_index([['a', DESCENDING], ['b', ASCENDING], ['c', DESCENDING]])
305
+ info = @@db.index_information(@@coll.name)
306
+ assert_equal 2, info.length
307
+
308
+ assert_equal name, 'a_-1_b_1_c_-1'
309
+ assert info.has_key?(name)
310
+ assert_equal info[name]['key'], {"a" => -1, "b" => 1, "c" => -1}
311
+ ensure
312
+ @@db.drop_index(@@coll.name, name)
313
+ end
314
+
315
+ def test_multiple_index_cols_with_symbols
316
+ name = @@coll.create_index([[:a, DESCENDING], [:b, ASCENDING], [:c, DESCENDING]])
317
+ info = @@db.index_information(@@coll.name)
318
+ assert_equal 2, info.length
319
+
320
+ assert_equal name, 'a_-1_b_1_c_-1'
321
+ assert info.has_key?(name)
322
+ assert_equal info[name]['key'], {"a" => -1, "b" => 1, "c" => -1}
323
+ ensure
324
+ @@db.drop_index(@@coll.name, name)
325
+ end
326
+
327
+ def test_unique_index
328
+ @@db.drop_collection("blah")
329
+ test = @@db.collection("blah")
330
+ test.create_index("hello")
331
+
332
+ test.insert("hello" => "world")
333
+ test.insert("hello" => "mike")
334
+ test.insert("hello" => "world")
335
+ assert !@@db.error?
336
+
337
+ @@db.drop_collection("blah")
338
+ test = @@db.collection("blah")
339
+ test.create_index("hello", :unique => true)
340
+
341
+ test.insert("hello" => "world")
342
+ test.insert("hello" => "mike")
343
+ test.insert("hello" => "world")
344
+ assert @@db.error?
345
+ end
346
+
347
+ def test_index_on_subfield
348
+ @@db.drop_collection("blah")
349
+ test = @@db.collection("blah")
350
+
351
+ test.insert("hello" => {"a" => 4, "b" => 5})
352
+ test.insert("hello" => {"a" => 7, "b" => 2})
353
+ test.insert("hello" => {"a" => 4, "b" => 10})
354
+ assert !@@db.error?
355
+
356
+ @@db.drop_collection("blah")
357
+ test = @@db.collection("blah")
358
+ test.create_index("hello.a", :unique => true)
359
+
360
+ test.insert("hello" => {"a" => 4, "b" => 5})
361
+ test.insert("hello" => {"a" => 7, "b" => 2})
362
+ test.insert("hello" => {"a" => 4, "b" => 10})
363
+ assert @@db.error?
364
+ end
365
+
366
+ def test_array
367
+ @@coll.remove
368
+ @@coll.insert({'b' => [1, 2, 3]})
369
+ @@coll.insert({'b' => [1, 2, 3]})
370
+ rows = @@coll.find({}, {:fields => ['b']}).to_a
371
+ assert_equal 2, rows.length
372
+ assert_equal [1, 2, 3], rows[1]['b']
373
+ end
374
+
375
+ def test_regex
376
+ regex = /foobar/i
377
+ @@coll << {'b' => regex}
378
+ rows = @@coll.find({}, {:fields => ['b']}).to_a
379
+ if @@version < "1.1.3"
380
+ assert_equal 1, rows.length
381
+ assert_equal regex, rows[0]['b']
382
+ else
383
+ assert_equal 2, rows.length
384
+ assert_equal regex, rows[1]['b']
385
+ end
386
+ end
387
+
388
+ def test_non_oid_id
389
+ # Note: can't use Time.new because that will include fractional seconds,
390
+ # which Mongo does not store.
391
+ t = Time.at(1234567890)
392
+ @@coll << {'_id' => t}
393
+ rows = @@coll.find({'_id' => t}).to_a
394
+ assert_equal 1, rows.length
395
+ assert_equal t, rows[0]['_id']
396
+ end
397
+
398
+ def test_strict
399
+ assert !@@db.strict?
400
+ @@db.strict = true
401
+ assert @@db.strict?
402
+ ensure
403
+ @@db.strict = false
404
+ end
405
+
406
+ def test_strict_access_collection
407
+ @@db.strict = true
408
+ begin
409
+ @@db.collection('does-not-exist')
410
+ fail "expected exception"
411
+ rescue => ex
412
+ assert_equal Mongo::MongoDBError, ex.class
413
+ assert_equal "Collection does-not-exist doesn't exist. Currently in strict mode.", ex.to_s
414
+ ensure
415
+ @@db.strict = false
416
+ @@db.drop_collection('does-not-exist')
417
+ end
418
+ end
419
+
420
+ def test_strict_create_collection
421
+ @@db.drop_collection('foobar')
422
+ @@db.strict = true
423
+
424
+ begin
425
+ @@db.create_collection('foobar')
426
+ assert true
427
+ rescue => ex
428
+ fail "did not expect exception \"#{ex}\""
429
+ end
430
+
431
+ # Now the collection exists. This time we should see an exception.
432
+ assert_raise Mongo::MongoDBError do
433
+ @@db.create_collection('foobar')
434
+ end
435
+ @@db.strict = false
436
+ @@db.drop_collection('foobar')
437
+
438
+ # Now we're not in strict mode - should succeed
439
+ @@db.create_collection('foobar')
440
+ @@db.create_collection('foobar')
441
+ @@db.drop_collection('foobar')
442
+ end
443
+
444
+ def test_where
445
+ @@coll.insert('a' => 2)
446
+ @@coll.insert('a' => 3)
447
+
448
+ assert_equal 3, @@coll.count
449
+ assert_equal 1, @@coll.find('$where' => BSON::Code.new('this.a > 2')).count()
450
+ assert_equal 2, @@coll.find('$where' => BSON::Code.new('this.a > i', {'i' => 1})).count()
451
+ end
452
+
453
+ def test_eval
454
+ assert_equal 3, @@db.eval('function (x) {return x;}', 3)
455
+
456
+ assert_equal nil, @@db.eval("function (x) {db.test_eval.save({y:x});}", 5)
457
+ assert_equal 5, @@db.collection('test_eval').find_one['y']
458
+
459
+ assert_equal 5, @@db.eval("function (x, y) {return x + y;}", 2, 3)
460
+ assert_equal 5, @@db.eval("function () {return 5;}")
461
+ assert_equal 5, @@db.eval("2 + 3;")
462
+
463
+ assert_equal 5, @@db.eval(Code.new("2 + 3;"))
464
+ assert_equal 2, @@db.eval(Code.new("return i;", {"i" => 2}))
465
+ assert_equal 5, @@db.eval(Code.new("i + 3;", {"i" => 2}))
466
+
467
+ assert_raise OperationFailure do
468
+ @@db.eval("5 ++ 5;")
469
+ end
470
+ end
471
+
472
+ def test_hint
473
+ name = @@coll.create_index('a')
474
+ begin
475
+ assert_nil @@coll.hint
476
+ assert_equal 1, @@coll.find({'a' => 1}, :hint => 'a').to_a.size
477
+ assert_equal 1, @@coll.find({'a' => 1}, :hint => ['a']).to_a.size
478
+ assert_equal 1, @@coll.find({'a' => 1}, :hint => {'a' => 1}).to_a.size
479
+
480
+ @@coll.hint = 'a'
481
+ assert_equal({'a' => 1}, @@coll.hint)
482
+ assert_equal 1, @@coll.find('a' => 1).to_a.size
483
+
484
+ @@coll.hint = ['a']
485
+ assert_equal({'a' => 1}, @@coll.hint)
486
+ assert_equal 1, @@coll.find('a' => 1).to_a.size
487
+
488
+ @@coll.hint = {'a' => 1}
489
+ assert_equal({'a' => 1}, @@coll.hint)
490
+ assert_equal 1, @@coll.find('a' => 1).to_a.size
491
+
492
+ @@coll.hint = nil
493
+ assert_nil @@coll.hint
494
+ assert_equal 1, @@coll.find('a' => 1).to_a.size
495
+ ensure
496
+ @@coll.drop_index(name)
497
+ end
498
+ end
499
+
500
+ def test_hash_default_value_id
501
+ val = Hash.new(0)
502
+ val["x"] = 5
503
+ @@coll.insert val
504
+ id = @@coll.find_one("x" => 5)["_id"]
505
+ assert id != 0
506
+ end
507
+
508
+ def test_group
509
+ @@db.drop_collection("test")
510
+ test = @@db.collection("test")
511
+
512
+ assert_equal [], test.group(:initial => {"count" => 0}, :reduce => "function (obj, prev) { prev.count++; }")
513
+ assert_equal [], test.group(:initial => {"count" => 0}, :reduce => "function (obj, prev) { prev.count++; }")
514
+
515
+ test.insert("a" => 2)
516
+ test.insert("b" => 5)
517
+ test.insert("a" => 1)
518
+
519
+ assert_equal 3, test.group(:initial => {"count" => 0},
520
+ :reduce => "function (obj, prev) { prev.count++; }")[0]["count"]
521
+ assert_equal 3, test.group(:initial => {"count" => 0},
522
+ :reduce => "function (obj, prev) { prev.count++; }")[0]["count"]
523
+ assert_equal 1, test.group(:cond => {"a" => {"$gt" => 1}},
524
+ :initial => {"count" => 0}, :reduce => "function (obj, prev) { prev.count++; }")[0]["count"]
525
+ assert_equal 1, test.group(:cond => {"a" => {"$gt" => 1}},
526
+ :initial => {"count" => 0}, :reduce => "function (obj, prev) { prev.count++; }")[0]["count"]
527
+
528
+ finalize = "function (obj) { obj.f = obj.count - 1; }"
529
+ assert_equal 2, test.group(:initial => {"count" => 0},
530
+ :reduce => "function (obj, prev) { prev.count++; }", :finalize => finalize)[0]["f"]
531
+
532
+ test.insert("a" => 2, "b" => 3)
533
+ expected = [{"a" => 2, "count" => 2},
534
+ {"a" => nil, "count" => 1},
535
+ {"a" => 1, "count" => 1}]
536
+ assert_equal expected, test.group(:key => ["a"], :initial => {"count" => 0},
537
+ :reduce => "function (obj, prev) { prev.count++; }")
538
+ assert_equal expected, test.group(:key => :a, :initial => {"count" => 0},
539
+ :reduce => "function (obj, prev) { prev.count++; }")
540
+
541
+ assert_raise OperationFailure do
542
+ test.group(:initial => {}, :reduce => "5 ++ 5")
543
+ end
544
+ end
545
+
546
+ def test_deref
547
+ @@coll.remove
548
+
549
+ assert_equal nil, @@db.dereference(DBRef.new("test", ObjectId.new))
550
+ @@coll.insert({"x" => "hello"})
551
+ key = @@coll.find_one()["_id"]
552
+ assert_equal "hello", @@db.dereference(DBRef.new("test", key))["x"]
553
+
554
+ assert_equal nil, @@db.dereference(DBRef.new("test", 4))
555
+ obj = {"_id" => 4}
556
+ @@coll.insert(obj)
557
+ assert_equal obj, @@db.dereference(DBRef.new("test", 4))
558
+
559
+ @@coll.remove
560
+ @@coll.insert({"x" => "hello"})
561
+ assert_equal nil, @@db.dereference(DBRef.new("test", nil))
562
+ end
563
+
564
+ def test_save
565
+ @@coll.remove
566
+
567
+ a = {"hello" => "world"}
568
+
569
+ id = @@coll.save(a)
570
+ assert_kind_of ObjectId, id
571
+ assert_equal 1, @@coll.count
572
+
573
+ assert_equal id, @@coll.save(a)
574
+ assert_equal 1, @@coll.count
575
+
576
+ assert_equal "world", @@coll.find_one()["hello"]
577
+
578
+ a["hello"] = "mike"
579
+ @@coll.save(a)
580
+ assert_equal 1, @@coll.count
581
+
582
+ assert_equal "mike", @@coll.find_one()["hello"]
583
+
584
+ @@coll.save({"hello" => "world"})
585
+ assert_equal 2, @@coll.count
586
+ end
587
+
588
+ def test_save_long
589
+ @@coll.remove
590
+ @@coll.insert("x" => 9223372036854775807)
591
+ assert_equal 9223372036854775807, @@coll.find_one()["x"]
592
+ end
593
+
594
+ def test_find_by_oid
595
+ @@coll.remove
596
+
597
+ @@coll.save("hello" => "mike")
598
+ id = @@coll.save("hello" => "world")
599
+ assert_kind_of ObjectId, id
600
+
601
+ assert_equal "world", @@coll.find_one(:_id => id)["hello"]
602
+ @@coll.find(:_id => id).to_a.each do |doc|
603
+ assert_equal "world", doc["hello"]
604
+ end
605
+
606
+ id = ObjectId.from_string(id.to_s)
607
+ assert_equal "world", @@coll.find_one(:_id => id)["hello"]
608
+ end
609
+
610
+ def test_save_with_object_that_has_id_but_does_not_actually_exist_in_collection
611
+ @@coll.remove
612
+
613
+ a = {'_id' => '1', 'hello' => 'world'}
614
+ @@coll.save(a)
615
+ assert_equal(1, @@coll.count)
616
+ assert_equal("world", @@coll.find_one()["hello"])
617
+
618
+ a["hello"] = "mike"
619
+ @@coll.save(a)
620
+ assert_equal(1, @@coll.count)
621
+ assert_equal("mike", @@coll.find_one()["hello"])
622
+ end
623
+
624
+ def test_collection_names
625
+ assert_raise TypeError do
626
+ @@db.collection(5)
627
+ end
628
+ assert_raise Mongo::InvalidNSName do
629
+ @@db.collection("")
630
+ end
631
+ assert_raise Mongo::InvalidNSName do
632
+ @@db.collection("te$t")
633
+ end
634
+ assert_raise Mongo::InvalidNSName do
635
+ @@db.collection(".test")
636
+ end
637
+ assert_raise Mongo::InvalidNSName do
638
+ @@db.collection("test.")
639
+ end
640
+ assert_raise Mongo::InvalidNSName do
641
+ @@db.collection("tes..t")
642
+ end
643
+ end
644
+
645
+ def test_rename_collection
646
+ @@db.drop_collection("foo")
647
+ @@db.drop_collection("bar")
648
+ a = @@db.collection("foo")
649
+ b = @@db.collection("bar")
650
+
651
+ assert_raise TypeError do
652
+ a.rename(5)
653
+ end
654
+ assert_raise Mongo::InvalidNSName do
655
+ a.rename("")
656
+ end
657
+ assert_raise Mongo::InvalidNSName do
658
+ a.rename("te$t")
659
+ end
660
+ assert_raise Mongo::InvalidNSName do
661
+ a.rename(".test")
662
+ end
663
+ assert_raise Mongo::InvalidNSName do
664
+ a.rename("test.")
665
+ end
666
+ assert_raise Mongo::InvalidNSName do
667
+ a.rename("tes..t")
668
+ end
669
+
670
+ assert_equal 0, a.count()
671
+ assert_equal 0, b.count()
672
+
673
+ a.insert("x" => 1)
674
+ a.insert("x" => 2)
675
+
676
+ assert_equal 2, a.count()
677
+
678
+ a.rename("bar")
679
+
680
+ assert_equal 2, a.count()
681
+ end
682
+
683
+ # doesn't really test functionality, just that the option is set correctly
684
+ def test_snapshot
685
+ @@db.collection("test").find({}, :snapshot => true).to_a
686
+ assert_raise OperationFailure do
687
+ @@db.collection("test").find({}, :snapshot => true, :sort => 'a').to_a
688
+ end
689
+ end
690
+
691
+ def test_encodings
692
+ if RUBY_VERSION >= '1.9'
693
+ ascii = "hello world"
694
+ utf8 = "hello world".encode("UTF-8")
695
+ iso8859 = "hello world".encode("ISO-8859-1")
696
+
697
+ if RUBY_PLATFORM =~ /jruby/
698
+ assert_equal "ASCII-8BIT", ascii.encoding.name
699
+ else
700
+ assert_equal "US-ASCII", ascii.encoding.name
701
+ end
702
+
703
+ assert_equal "UTF-8", utf8.encoding.name
704
+ assert_equal "ISO-8859-1", iso8859.encoding.name
705
+
706
+ @@coll.remove
707
+ @@coll.save("ascii" => ascii, "utf8" => utf8, "iso8859" => iso8859)
708
+ doc = @@coll.find_one()
709
+
710
+ assert_equal "UTF-8", doc["ascii"].encoding.name
711
+ assert_equal "UTF-8", doc["utf8"].encoding.name
712
+ assert_equal "UTF-8", doc["iso8859"].encoding.name
713
+ end
714
+ end
715
+ end