mongo 1.10.0-java

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 (116) hide show
  1. checksums.yaml +7 -0
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/LICENSE +190 -0
  5. data/README.md +149 -0
  6. data/Rakefile +31 -0
  7. data/VERSION +1 -0
  8. data/bin/mongo_console +43 -0
  9. data/ext/jsasl/target/jsasl.jar +0 -0
  10. data/lib/mongo.rb +90 -0
  11. data/lib/mongo/bulk_write_collection_view.rb +380 -0
  12. data/lib/mongo/collection.rb +1164 -0
  13. data/lib/mongo/collection_writer.rb +364 -0
  14. data/lib/mongo/connection.rb +19 -0
  15. data/lib/mongo/connection/node.rb +239 -0
  16. data/lib/mongo/connection/pool.rb +347 -0
  17. data/lib/mongo/connection/pool_manager.rb +325 -0
  18. data/lib/mongo/connection/sharding_pool_manager.rb +67 -0
  19. data/lib/mongo/connection/socket.rb +18 -0
  20. data/lib/mongo/connection/socket/socket_util.rb +37 -0
  21. data/lib/mongo/connection/socket/ssl_socket.rb +95 -0
  22. data/lib/mongo/connection/socket/tcp_socket.rb +86 -0
  23. data/lib/mongo/connection/socket/unix_socket.rb +39 -0
  24. data/lib/mongo/cursor.rb +719 -0
  25. data/lib/mongo/db.rb +735 -0
  26. data/lib/mongo/exception.rb +88 -0
  27. data/lib/mongo/functional.rb +21 -0
  28. data/lib/mongo/functional/authentication.rb +318 -0
  29. data/lib/mongo/functional/logging.rb +85 -0
  30. data/lib/mongo/functional/read_preference.rb +174 -0
  31. data/lib/mongo/functional/sasl_java.rb +48 -0
  32. data/lib/mongo/functional/uri_parser.rb +374 -0
  33. data/lib/mongo/functional/write_concern.rb +66 -0
  34. data/lib/mongo/gridfs.rb +18 -0
  35. data/lib/mongo/gridfs/grid.rb +112 -0
  36. data/lib/mongo/gridfs/grid_ext.rb +53 -0
  37. data/lib/mongo/gridfs/grid_file_system.rb +163 -0
  38. data/lib/mongo/gridfs/grid_io.rb +484 -0
  39. data/lib/mongo/legacy.rb +140 -0
  40. data/lib/mongo/mongo_client.rb +702 -0
  41. data/lib/mongo/mongo_replica_set_client.rb +523 -0
  42. data/lib/mongo/mongo_sharded_client.rb +159 -0
  43. data/lib/mongo/networking.rb +370 -0
  44. data/lib/mongo/utils.rb +19 -0
  45. data/lib/mongo/utils/conversions.rb +110 -0
  46. data/lib/mongo/utils/core_ext.rb +70 -0
  47. data/lib/mongo/utils/server_version.rb +69 -0
  48. data/lib/mongo/utils/support.rb +80 -0
  49. data/lib/mongo/utils/thread_local_variable_manager.rb +25 -0
  50. data/mongo.gemspec +36 -0
  51. data/test/functional/authentication_test.rb +35 -0
  52. data/test/functional/bulk_api_stress_test.rb +133 -0
  53. data/test/functional/bulk_write_collection_view_test.rb +1129 -0
  54. data/test/functional/client_test.rb +565 -0
  55. data/test/functional/collection_test.rb +2073 -0
  56. data/test/functional/collection_writer_test.rb +83 -0
  57. data/test/functional/conversions_test.rb +163 -0
  58. data/test/functional/cursor_fail_test.rb +63 -0
  59. data/test/functional/cursor_message_test.rb +57 -0
  60. data/test/functional/cursor_test.rb +625 -0
  61. data/test/functional/db_api_test.rb +819 -0
  62. data/test/functional/db_connection_test.rb +27 -0
  63. data/test/functional/db_test.rb +344 -0
  64. data/test/functional/grid_file_system_test.rb +285 -0
  65. data/test/functional/grid_io_test.rb +252 -0
  66. data/test/functional/grid_test.rb +273 -0
  67. data/test/functional/pool_test.rb +62 -0
  68. data/test/functional/safe_test.rb +98 -0
  69. data/test/functional/ssl_test.rb +29 -0
  70. data/test/functional/support_test.rb +62 -0
  71. data/test/functional/timeout_test.rb +58 -0
  72. data/test/functional/uri_test.rb +330 -0
  73. data/test/functional/write_concern_test.rb +118 -0
  74. data/test/helpers/general.rb +50 -0
  75. data/test/helpers/test_unit.rb +317 -0
  76. data/test/replica_set/authentication_test.rb +35 -0
  77. data/test/replica_set/basic_test.rb +174 -0
  78. data/test/replica_set/client_test.rb +341 -0
  79. data/test/replica_set/complex_connect_test.rb +77 -0
  80. data/test/replica_set/connection_test.rb +138 -0
  81. data/test/replica_set/count_test.rb +64 -0
  82. data/test/replica_set/cursor_test.rb +212 -0
  83. data/test/replica_set/insert_test.rb +140 -0
  84. data/test/replica_set/max_values_test.rb +145 -0
  85. data/test/replica_set/pinning_test.rb +55 -0
  86. data/test/replica_set/query_test.rb +73 -0
  87. data/test/replica_set/read_preference_test.rb +214 -0
  88. data/test/replica_set/refresh_test.rb +175 -0
  89. data/test/replica_set/replication_ack_test.rb +94 -0
  90. data/test/replica_set/ssl_test.rb +32 -0
  91. data/test/sharded_cluster/basic_test.rb +197 -0
  92. data/test/shared/authentication/basic_auth_shared.rb +286 -0
  93. data/test/shared/authentication/bulk_api_auth_shared.rb +259 -0
  94. data/test/shared/authentication/gssapi_shared.rb +164 -0
  95. data/test/shared/authentication/sasl_plain_shared.rb +96 -0
  96. data/test/shared/ssl_shared.rb +235 -0
  97. data/test/test_helper.rb +56 -0
  98. data/test/threading/basic_test.rb +120 -0
  99. data/test/tools/mongo_config.rb +608 -0
  100. data/test/tools/mongo_config_test.rb +160 -0
  101. data/test/unit/client_test.rb +347 -0
  102. data/test/unit/collection_test.rb +166 -0
  103. data/test/unit/connection_test.rb +325 -0
  104. data/test/unit/cursor_test.rb +299 -0
  105. data/test/unit/db_test.rb +136 -0
  106. data/test/unit/grid_test.rb +76 -0
  107. data/test/unit/mongo_sharded_client_test.rb +48 -0
  108. data/test/unit/node_test.rb +93 -0
  109. data/test/unit/pool_manager_test.rb +142 -0
  110. data/test/unit/read_pref_test.rb +115 -0
  111. data/test/unit/read_test.rb +159 -0
  112. data/test/unit/safe_test.rb +158 -0
  113. data/test/unit/sharding_pool_manager_test.rb +84 -0
  114. data/test/unit/write_concern_test.rb +175 -0
  115. metadata +260 -0
  116. metadata.gz.sig +0 -0
@@ -0,0 +1,819 @@
1
+ # Copyright (C) 2009-2013 MongoDB, Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ require 'test_helper'
16
+
17
+ class DBAPITest < Test::Unit::TestCase
18
+ include Mongo
19
+ include BSON
20
+
21
+ @@client = standard_connection
22
+ @@db = @@client.db(TEST_DB)
23
+ @@coll = @@db.collection('test')
24
+ @@version = @@client.server_version
25
+
26
+ def setup
27
+ @@coll.remove
28
+ @r1 = {'a' => 1}
29
+ @@coll.insert(@r1) # collection not created until it's used
30
+ @@coll_full_name = "#{TEST_DB}.test"
31
+ end
32
+
33
+ def teardown
34
+ @@coll.remove
35
+ @@db.get_last_error
36
+ end
37
+
38
+ def test_clear
39
+ assert_equal 1, @@coll.count
40
+ @@coll.remove
41
+ assert_equal 0, @@coll.count
42
+ end
43
+
44
+ def test_insert
45
+ assert_kind_of BSON::ObjectId, @@coll.insert('a' => 2)
46
+ assert_kind_of BSON::ObjectId, @@coll.insert('b' => 3)
47
+
48
+ assert_equal 3, @@coll.count
49
+ docs = @@coll.find().to_a
50
+ assert_equal 3, docs.length
51
+ assert docs.detect { |row| row['a'] == 1 }
52
+ assert docs.detect { |row| row['a'] == 2 }
53
+ assert docs.detect { |row| row['b'] == 3 }
54
+
55
+ @@coll << {'b' => 4}
56
+ docs = @@coll.find().to_a
57
+ assert_equal 4, docs.length
58
+ assert docs.detect { |row| row['b'] == 4 }
59
+ end
60
+
61
+ def test_save_ordered_hash
62
+ oh = BSON::OrderedHash.new
63
+ oh['a'] = -1
64
+ oh['b'] = 'foo'
65
+
66
+ oid = @@coll.save(oh)
67
+ assert_equal 'foo', @@coll.find_one(oid)['b']
68
+
69
+ oh = BSON::OrderedHash['a' => 1, 'b' => 'foo']
70
+ oid = @@coll.save(oh)
71
+ assert_equal 'foo', @@coll.find_one(oid)['b']
72
+ end
73
+
74
+ def test_insert_multiple
75
+ ids = @@coll.insert([{'a' => 2}, {'b' => 3}])
76
+
77
+ ids.each do |i|
78
+ assert_kind_of BSON::ObjectId, i
79
+ end
80
+
81
+ assert_equal 3, @@coll.count
82
+ docs = @@coll.find().to_a
83
+ assert_equal 3, docs.length
84
+ assert docs.detect { |row| row['a'] == 1 }
85
+ assert docs.detect { |row| row['a'] == 2 }
86
+ assert docs.detect { |row| row['b'] == 3 }
87
+ end
88
+
89
+ def test_count_on_nonexisting
90
+ @@db.drop_collection('foo')
91
+ assert_equal 0, @@db.collection('foo').count()
92
+ end
93
+
94
+ def test_find_simple
95
+ @r2 = @@coll.insert('a' => 2)
96
+ @r3 = @@coll.insert('b' => 3)
97
+ # Check sizes
98
+ docs = @@coll.find().to_a
99
+ assert_equal 3, docs.size
100
+ assert_equal 3, @@coll.count
101
+
102
+ # Find by other value
103
+ docs = @@coll.find('a' => @r1['a']).to_a
104
+ assert_equal 1, docs.size
105
+ doc = docs.first
106
+ # Can't compare _id values because at insert, an _id was added to @r1 by
107
+ # the database but we don't know what it is without re-reading the record
108
+ # (which is what we are doing right now).
109
+ # assert_equal doc['_id'], @r1['_id']
110
+ assert_equal doc['a'], @r1['a']
111
+ end
112
+
113
+ def test_find_advanced
114
+ @@coll.insert('a' => 2)
115
+ @@coll.insert('b' => 3)
116
+
117
+ # Find by advanced query (less than)
118
+ docs = @@coll.find('a' => { '$lt' => 10 }).to_a
119
+ assert_equal 2, docs.size
120
+ assert docs.detect { |row| row['a'] == 1 }
121
+ assert docs.detect { |row| row['a'] == 2 }
122
+
123
+ # Find by advanced query (greater than)
124
+ docs = @@coll.find('a' => { '$gt' => 1 }).to_a
125
+ assert_equal 1, docs.size
126
+ assert docs.detect { |row| row['a'] == 2 }
127
+
128
+ # Find by advanced query (less than or equal to)
129
+ docs = @@coll.find('a' => { '$lte' => 1 }).to_a
130
+ assert_equal 1, docs.size
131
+ assert docs.detect { |row| row['a'] == 1 }
132
+
133
+ # Find by advanced query (greater than or equal to)
134
+ docs = @@coll.find('a' => { '$gte' => 1 }).to_a
135
+ assert_equal 2, docs.size
136
+ assert docs.detect { |row| row['a'] == 1 }
137
+ assert docs.detect { |row| row['a'] == 2 }
138
+
139
+ # Find by advanced query (between)
140
+ docs = @@coll.find('a' => { '$gt' => 1, '$lt' => 3 }).to_a
141
+ assert_equal 1, docs.size
142
+ assert docs.detect { |row| row['a'] == 2 }
143
+
144
+ # Find by advanced query (in clause)
145
+ docs = @@coll.find('a' => {'$in' => [1,2]}).to_a
146
+ assert_equal 2, docs.size
147
+ assert docs.detect { |row| row['a'] == 1 }
148
+ assert docs.detect { |row| row['a'] == 2 }
149
+ end
150
+
151
+ def test_find_sorting
152
+ @@coll.remove
153
+ @@coll.insert('a' => 1, 'b' => 2)
154
+ @@coll.insert('a' => 2, 'b' => 1)
155
+ @@coll.insert('a' => 3, 'b' => 2)
156
+ @@coll.insert('a' => 4, 'b' => 1)
157
+
158
+ # Sorting (ascending)
159
+ docs = @@coll.find({'a' => { '$lt' => 10 }}, :sort => [['a', 1]]).to_a
160
+ assert_equal 4, docs.size
161
+ assert_equal 1, docs[0]['a']
162
+ assert_equal 2, docs[1]['a']
163
+ assert_equal 3, docs[2]['a']
164
+ assert_equal 4, docs[3]['a']
165
+
166
+ # Sorting (descending)
167
+ docs = @@coll.find({'a' => { '$lt' => 10 }}, :sort => [['a', -1]]).to_a
168
+ assert_equal 4, docs.size
169
+ assert_equal 4, docs[0]['a']
170
+ assert_equal 3, docs[1]['a']
171
+ assert_equal 2, docs[2]['a']
172
+ assert_equal 1, docs[3]['a']
173
+
174
+ # Sorting using array of names; assumes ascending order.
175
+ docs = @@coll.find({'a' => { '$lt' => 10 }}, :sort => 'a').to_a
176
+ assert_equal 4, docs.size
177
+ assert_equal 1, docs[0]['a']
178
+ assert_equal 2, docs[1]['a']
179
+ assert_equal 3, docs[2]['a']
180
+ assert_equal 4, docs[3]['a']
181
+
182
+ # Sorting using single name; assumes ascending order.
183
+ docs = @@coll.find({'a' => { '$lt' => 10 }}, :sort => 'a').to_a
184
+ assert_equal 4, docs.size
185
+ assert_equal 1, docs[0]['a']
186
+ assert_equal 2, docs[1]['a']
187
+ assert_equal 3, docs[2]['a']
188
+ assert_equal 4, docs[3]['a']
189
+
190
+ docs = @@coll.find({'a' => { '$lt' => 10 }}, :sort => [['b', 'asc'], ['a', 'asc']]).to_a
191
+ assert_equal 4, docs.size
192
+ assert_equal 2, docs[0]['a']
193
+ assert_equal 4, docs[1]['a']
194
+ assert_equal 1, docs[2]['a']
195
+ assert_equal 3, docs[3]['a']
196
+
197
+ # Sorting using empty array; no order guarantee should not blow up.
198
+ docs = @@coll.find({'a' => { '$lt' => 10 }}, :sort => []).to_a
199
+ assert_equal 4, docs.size
200
+ end
201
+
202
+ def test_find_sorting_with_hash
203
+ # Sorting using ordered hash. You can use an unordered one, but then the
204
+ # order of the keys won't be guaranteed thus your sort won't make sense.
205
+
206
+ @@coll.remove
207
+ @@coll.insert('a' => 1, 'b' => 2)
208
+ @@coll.insert('a' => 2, 'b' => 1)
209
+ @@coll.insert('a' => 3, 'b' => 2)
210
+ @@coll.insert('a' => 4, 'b' => 1)
211
+
212
+ oh = BSON::OrderedHash.new
213
+ oh['a'] = -1
214
+
215
+ # Sort as a method
216
+ docs = @@coll.find.sort(oh).to_a
217
+ assert_equal 4, docs.size
218
+ assert_equal 4, docs[0]['a']
219
+ assert_equal 3, docs[1]['a']
220
+ assert_equal 2, docs[2]['a']
221
+ assert_equal 1, docs[3]['a']
222
+
223
+ # Sort as an option
224
+ docs = @@coll.find({}, :sort => oh).to_a
225
+ assert_equal 4, docs.size
226
+ assert_equal 4, docs[0]['a']
227
+ assert_equal 3, docs[1]['a']
228
+ assert_equal 2, docs[2]['a']
229
+ assert_equal 1, docs[3]['a']
230
+
231
+ if RUBY_VERSION > '1.9'
232
+ docs = @@coll.find({}, :sort => {:a => -1}).to_a
233
+ assert_equal 4, docs.size
234
+ assert_equal 4, docs[0]['a']
235
+ assert_equal 3, docs[1]['a']
236
+ assert_equal 2, docs[2]['a']
237
+ assert_equal 1, docs[3]['a']
238
+
239
+ docs = @@coll.find.sort(:a => -1).to_a
240
+ assert_equal 4, docs.size
241
+ assert_equal 4, docs[0]['a']
242
+ assert_equal 3, docs[1]['a']
243
+ assert_equal 2, docs[2]['a']
244
+ assert_equal 1, docs[3]['a']
245
+
246
+ docs = @@coll.find.sort(:b => -1, :a => 1).to_a
247
+ assert_equal 4, docs.size
248
+ assert_equal 1, docs[0]['a']
249
+ assert_equal 3, docs[1]['a']
250
+ assert_equal 2, docs[2]['a']
251
+ assert_equal 4, docs[3]['a']
252
+ else
253
+ # Sort as an option
254
+ assert_raise InvalidSortValueError do
255
+ @@coll.find({}, :sort => {:a => -1}).to_a
256
+ end
257
+ # Sort as a method
258
+ assert_raise InvalidSortValueError do
259
+ @@coll.find.sort(:a => -1).to_a
260
+ end
261
+ end
262
+ end
263
+
264
+ def test_find_limits
265
+ @@coll.insert('b' => 2)
266
+ @@coll.insert('c' => 3)
267
+ @@coll.insert('d' => 4)
268
+
269
+ docs = @@coll.find({}, :limit => 1).to_a
270
+ assert_equal 1, docs.size
271
+ docs = @@coll.find({}, :limit => 2).to_a
272
+ assert_equal 2, docs.size
273
+ docs = @@coll.find({}, :limit => 3).to_a
274
+ assert_equal 3, docs.size
275
+ docs = @@coll.find({}, :limit => 4).to_a
276
+ assert_equal 4, docs.size
277
+ docs = @@coll.find({}).to_a
278
+ assert_equal 4, docs.size
279
+ docs = @@coll.find({}, :limit => 99).to_a
280
+ assert_equal 4, docs.size
281
+ end
282
+
283
+ def test_find_one_no_records
284
+ @@coll.remove
285
+ x = @@coll.find_one('a' => 1)
286
+ assert_nil x
287
+ end
288
+
289
+ def test_drop_collection
290
+ assert @@db.drop_collection(@@coll.name), "drop of collection #{@@coll.name} failed"
291
+ assert !@@db.collection_names.include?(@@coll.name)
292
+ end
293
+
294
+ def test_other_drop
295
+ assert @@db.collection_names.include?(@@coll.name)
296
+ @@coll.drop
297
+ assert !@@db.collection_names.include?(@@coll.name)
298
+ end
299
+
300
+ def test_collection_names
301
+ names = @@db.collection_names
302
+ assert names.length >= 1
303
+ assert names.include?(@@coll.name)
304
+
305
+ coll2 = @@db.collection('test2')
306
+ coll2.insert('a' => 1) # collection not created until it's used
307
+ names = @@db.collection_names
308
+ assert names.length >= 2
309
+ assert names.include?(@@coll.name)
310
+ assert names.include?('test2')
311
+ ensure
312
+ @@db.drop_collection('test2')
313
+ end
314
+
315
+ def test_collections_info
316
+ cursor = @@db.collections_info
317
+ rows = cursor.to_a
318
+ assert rows.length >= 1
319
+ row = rows.detect { |r| r['name'] == @@coll_full_name }
320
+ assert_not_nil row
321
+ end
322
+
323
+ def test_collection_options
324
+ @@db.drop_collection('foobar')
325
+ @@db.strict = true
326
+
327
+ begin
328
+ coll = @@db.create_collection('foobar', :capped => true, :size => 4096)
329
+ options = coll.options
330
+ assert_equal 'foobar', options['create'] if @@client.server_version < '2.5.5'
331
+ assert_equal true, options['capped']
332
+ assert_equal 4096, options['size']
333
+ rescue => ex
334
+ @@db.drop_collection('foobar')
335
+ fail "did not expect exception \"#{ex.inspect}\""
336
+ ensure
337
+ @@db.strict = false
338
+ end
339
+ end
340
+
341
+ def test_collection_options_are_passed_to_the_existing_ones
342
+ @@db.drop_collection('foobar')
343
+
344
+ @@db.create_collection('foobar')
345
+
346
+ coll = @@db.create_collection('foobar')
347
+ assert_equal true, Mongo::WriteConcern.gle?(coll.write_concern)
348
+ end
349
+
350
+
351
+ def test_index_information
352
+ assert_equal @@coll.index_information.length, 1
353
+
354
+ name = @@coll.create_index('a')
355
+ info = @@db.index_information(@@coll.name)
356
+ assert_equal name, "a_1"
357
+ assert_equal @@coll.index_information, info
358
+ assert_equal 2, info.length
359
+
360
+ assert info.has_key?(name)
361
+ assert_equal info[name]["key"], {"a" => 1}
362
+ ensure
363
+ @@db.drop_index(@@coll.name, name)
364
+ end
365
+
366
+ def test_index_create_with_symbol
367
+ assert_equal @@coll.index_information.length, 1
368
+
369
+ name = @@coll.create_index([['a', 1]])
370
+ info = @@db.index_information(@@coll.name)
371
+ assert_equal name, "a_1"
372
+ assert_equal @@coll.index_information, info
373
+ assert_equal 2, info.length
374
+
375
+ assert info.has_key?(name)
376
+ assert_equal info[name]['key'], {"a" => 1}
377
+ ensure
378
+ @@db.drop_index(@@coll.name, name)
379
+ end
380
+
381
+ def test_multiple_index_cols
382
+ name = @@coll.create_index([['a', DESCENDING], ['b', ASCENDING], ['c', DESCENDING]])
383
+ info = @@db.index_information(@@coll.name)
384
+ assert_equal 2, info.length
385
+
386
+ assert_equal name, 'a_-1_b_1_c_-1'
387
+ assert info.has_key?(name)
388
+ assert_equal info[name]['key'], {"a" => -1, "b" => 1, "c" => -1}
389
+ ensure
390
+ @@db.drop_index(@@coll.name, name)
391
+ end
392
+
393
+ def test_multiple_index_cols_with_symbols
394
+ name = @@coll.create_index([[:a, DESCENDING], [:b, ASCENDING], [:c, DESCENDING]])
395
+ info = @@db.index_information(@@coll.name)
396
+ assert_equal 2, info.length
397
+
398
+ assert_equal name, 'a_-1_b_1_c_-1'
399
+ assert info.has_key?(name)
400
+ assert_equal info[name]['key'], {"a" => -1, "b" => 1, "c" => -1}
401
+ ensure
402
+ @@db.drop_index(@@coll.name, name)
403
+ end
404
+
405
+ def test_unique_index
406
+ @@db.drop_collection("blah")
407
+ test = @@db.collection("blah")
408
+ test.create_index("hello")
409
+
410
+ test.insert("hello" => "world")
411
+ test.insert("hello" => "mike")
412
+ test.insert("hello" => "world")
413
+ assert !@@db.error?
414
+
415
+ @@db.drop_collection("blah")
416
+ test = @@db.collection("blah")
417
+ test.create_index("hello", :unique => true)
418
+
419
+ test.insert("hello" => "world")
420
+ test.insert("hello" => "mike")
421
+ assert_raise OperationFailure do
422
+ test.insert("hello" => "world")
423
+ end
424
+ end
425
+
426
+ def test_index_on_subfield
427
+ @@db.drop_collection("blah")
428
+ test = @@db.collection("blah")
429
+
430
+ test.insert("hello" => {"a" => 4, "b" => 5})
431
+ test.insert("hello" => {"a" => 7, "b" => 2})
432
+ test.insert("hello" => {"a" => 4, "b" => 10})
433
+ assert !@@db.error?
434
+
435
+ @@db.drop_collection("blah")
436
+ test = @@db.collection("blah")
437
+ test.create_index("hello.a", :unique => true)
438
+
439
+ test.insert("hello" => {"a" => 4, "b" => 5})
440
+ test.insert("hello" => {"a" => 7, "b" => 2})
441
+ assert_raise OperationFailure do
442
+ test.insert("hello" => {"a" => 4, "b" => 10} )
443
+ end
444
+ end
445
+
446
+ def test_array
447
+ @@coll.remove({'$atomic' => true})
448
+ @@coll.insert({'b' => [1, 2, 3]})
449
+ @@coll.insert({'b' => [1, 2, 3]})
450
+ rows = @@coll.find({}, {:fields => ['b']}).to_a
451
+ assert_equal 2, rows.length
452
+ assert_equal [1, 2, 3], rows[1]['b']
453
+ end
454
+
455
+ def test_regex
456
+ regex = /foobar/i
457
+ @@coll << {'b' => regex}
458
+ rows = @@coll.find({}, {:fields => ['b']}).to_a
459
+ if @@version < "1.1.3"
460
+ assert_equal 1, rows.length
461
+ assert_equal regex, rows[0]['b']
462
+ else
463
+ assert_equal 2, rows.length
464
+ assert_equal regex, rows[1]['b']
465
+ end
466
+ end
467
+
468
+ def test_regex_multi_line
469
+ if @@version >= "1.9.1"
470
+ doc = <<HERE
471
+ the lazy brown
472
+ fox
473
+ HERE
474
+ @@coll.save({:doc => doc})
475
+ assert @@coll.find_one({:doc => /n.*x/m})
476
+ @@coll.remove
477
+ end
478
+ end
479
+
480
+ def test_non_oid_id
481
+ # Note: can't use Time.new because that will include fractional seconds,
482
+ # which Mongo does not store.
483
+ t = Time.at(1234567890)
484
+ @@coll << {'_id' => t}
485
+ rows = @@coll.find({'_id' => t}).to_a
486
+ assert_equal 1, rows.length
487
+ assert_equal t, rows[0]['_id']
488
+ end
489
+
490
+ def test_strict
491
+ assert !@@db.strict?
492
+ @@db.strict = true
493
+ assert @@db.strict?
494
+ ensure
495
+ @@db.strict = false
496
+ end
497
+
498
+ def test_strict_access_collection
499
+ @@db.strict = true
500
+ begin
501
+ @@db.collection('does-not-exist')
502
+ fail "expected exception"
503
+ rescue => ex
504
+ assert_equal Mongo::MongoDBError, ex.class
505
+ assert_equal "Collection 'does-not-exist' doesn't exist. (strict=true)", ex.to_s
506
+ ensure
507
+ @@db.strict = false
508
+ @@db.drop_collection('does-not-exist')
509
+ end
510
+ end
511
+
512
+ def test_strict_create_collection
513
+ @@db.drop_collection('foobar')
514
+ @@db.strict = true
515
+
516
+ begin
517
+ assert @@db.create_collection('foobar')
518
+ rescue => ex
519
+ fail "did not expect exception \"#{ex}\""
520
+ end
521
+
522
+ # Now the collection exists. This time we should see an exception.
523
+ assert_raise Mongo::MongoDBError do
524
+ @@db.create_collection('foobar')
525
+ end
526
+ @@db.strict = false
527
+ @@db.drop_collection('foobar')
528
+
529
+ # Now we're not in strict mode - should succeed
530
+ @@db.create_collection('foobar')
531
+ @@db.create_collection('foobar')
532
+ @@db.drop_collection('foobar')
533
+ end
534
+
535
+ def test_where
536
+ @@coll.insert('a' => 2)
537
+ @@coll.insert('a' => 3)
538
+
539
+ assert_equal 3, @@coll.count
540
+ assert_equal 1, @@coll.find('$where' => BSON::Code.new('this.a > 2')).count()
541
+ assert_equal 2, @@coll.find('$where' => BSON::Code.new('this.a > i', {'i' => 1})).count()
542
+ end
543
+
544
+ def test_eval
545
+ assert_equal 3, @@db.eval('function (x) {return x;}', 3)
546
+
547
+ assert_equal nil, @@db.eval("function (x) {db.test_eval.save({y:x});}", 5)
548
+ assert_equal 5, @@db.collection('test_eval').find_one['y']
549
+
550
+ assert_equal 5, @@db.eval("function (x, y) {return x + y;}", 2, 3)
551
+ assert_equal 5, @@db.eval("function () {return 5;}")
552
+ assert_equal 5, @@db.eval("2 + 3;")
553
+
554
+ assert_equal 5, @@db.eval(Code.new("2 + 3;"))
555
+ assert_equal 2, @@db.eval(Code.new("return i;", {"i" => 2}))
556
+ assert_equal 5, @@db.eval(Code.new("i + 3;", {"i" => 2}))
557
+
558
+ assert_raise OperationFailure do
559
+ @@db.eval("5 ++ 5;")
560
+ end
561
+ end
562
+
563
+ def test_hint
564
+ name = @@coll.create_index('a')
565
+ begin
566
+ assert_nil @@coll.hint
567
+ assert_equal 1, @@coll.find({'a' => 1}, :hint => 'a').to_a.size
568
+ assert_equal 1, @@coll.find({'a' => 1}, :hint => ['a']).to_a.size
569
+ assert_equal 1, @@coll.find({'a' => 1}, :hint => {'a' => 1}).to_a.size
570
+
571
+ @@coll.hint = 'a'
572
+ assert_equal({'a' => 1}, @@coll.hint)
573
+ assert_equal 1, @@coll.find('a' => 1).to_a.size
574
+
575
+ @@coll.hint = ['a']
576
+ assert_equal({'a' => 1}, @@coll.hint)
577
+ assert_equal 1, @@coll.find('a' => 1).to_a.size
578
+
579
+ @@coll.hint = {'a' => 1}
580
+ assert_equal({'a' => 1}, @@coll.hint)
581
+ assert_equal 1, @@coll.find('a' => 1).to_a.size
582
+
583
+ @@coll.hint = nil
584
+ assert_nil @@coll.hint
585
+ assert_equal 1, @@coll.find('a' => 1).to_a.size
586
+ ensure
587
+ @@coll.drop_index(name)
588
+ end
589
+ end
590
+
591
+ def test_named_hint
592
+ name = @@coll.create_index('a', :name => 'named_index')
593
+ begin
594
+ assert_nil @@coll.hint
595
+ assert_equal 1, @@coll.find({'a' => 1}, :named_hint => 'named_index').to_a.size
596
+ assert_equal 1, @@coll.find({'a' => 1}, :hint => 'a', :named_hint => "bad_hint").to_a.size
597
+ ensure
598
+ @@coll.drop_index('named_index')
599
+ end
600
+ end
601
+
602
+ def test_hash_default_value_id
603
+ val = Hash.new(0)
604
+ val["x"] = 5
605
+ @@coll.insert val
606
+ id = @@coll.find_one("x" => 5)["_id"]
607
+ assert id != 0
608
+ end
609
+
610
+ def test_group
611
+ @@db.drop_collection("test")
612
+ test = @@db.collection("test")
613
+
614
+ assert_equal [], test.group(:initial => {"count" => 0}, :reduce => "function (obj, prev) { prev.count++; }")
615
+ assert_equal [], test.group(:initial => {"count" => 0}, :reduce => "function (obj, prev) { prev.count++; }")
616
+
617
+ test.insert("a" => 2)
618
+ test.insert("b" => 5)
619
+ test.insert("a" => 1)
620
+
621
+ assert_equal 3, test.group(:initial => {"count" => 0},
622
+ :reduce => "function (obj, prev) { prev.count++; }")[0]["count"]
623
+ assert_equal 3, test.group(:initial => {"count" => 0},
624
+ :reduce => "function (obj, prev) { prev.count++; }")[0]["count"]
625
+ assert_equal 1, test.group(:cond => {"a" => {"$gt" => 1}},
626
+ :initial => {"count" => 0}, :reduce => "function (obj, prev) { prev.count++; }")[0]["count"]
627
+ assert_equal 1, test.group(:cond => {"a" => {"$gt" => 1}},
628
+ :initial => {"count" => 0}, :reduce => "function (obj, prev) { prev.count++; }")[0]["count"]
629
+
630
+ finalize = "function (obj) { obj.f = obj.count - 1; }"
631
+ assert_equal 2, test.group(:initial => {"count" => 0},
632
+ :reduce => "function (obj, prev) { prev.count++; }", :finalize => finalize)[0]["f"]
633
+
634
+ test.insert("a" => 2, "b" => 3)
635
+ expected = [{"a" => 2, "count" => 2},
636
+ {"a" => nil, "count" => 1},
637
+ {"a" => 1, "count" => 1}]
638
+ assert_equal expected, test.group(:key => ["a"], :initial => {"count" => 0},
639
+ :reduce => "function (obj, prev) { prev.count++; }")
640
+ assert_equal expected, test.group(:key => :a, :initial => {"count" => 0},
641
+ :reduce => "function (obj, prev) { prev.count++; }")
642
+
643
+ assert_raise OperationFailure do
644
+ test.group(:initial => {}, :reduce => "5 ++ 5")
645
+ end
646
+ end
647
+
648
+ def test_deref
649
+ @@coll.remove
650
+
651
+ assert_equal nil, @@db.dereference(DBRef.new("test", ObjectId.new))
652
+ @@coll.insert({"x" => "hello"})
653
+ key = @@coll.find_one()["_id"]
654
+ assert_equal "hello", @@db.dereference(DBRef.new("test", key))["x"]
655
+
656
+ assert_equal nil, @@db.dereference(DBRef.new("test", 4))
657
+ obj = {"_id" => 4}
658
+ @@coll.insert(obj)
659
+ assert_equal obj, @@db.dereference(DBRef.new("test", 4))
660
+
661
+ @@coll.remove
662
+ @@coll.insert({"x" => "hello"})
663
+ assert_equal nil, @@db.dereference(DBRef.new("test", nil))
664
+ end
665
+
666
+ def test_save
667
+ @@coll.remove
668
+
669
+ a = {"hello" => "world"}
670
+
671
+ id = @@coll.save(a)
672
+ assert_kind_of ObjectId, id
673
+ assert_equal 1, @@coll.count
674
+
675
+ assert_equal id, @@coll.save(a)
676
+ assert_equal 1, @@coll.count
677
+
678
+ assert_equal "world", @@coll.find_one()["hello"]
679
+
680
+ a["hello"] = "mike"
681
+ @@coll.save(a)
682
+ assert_equal 1, @@coll.count
683
+
684
+ assert_equal "mike", @@coll.find_one()["hello"]
685
+
686
+ @@coll.save({"hello" => "world"})
687
+ assert_equal 2, @@coll.count
688
+ end
689
+
690
+ def test_save_long
691
+ @@coll.remove
692
+ @@coll.insert("x" => 9223372036854775807)
693
+ assert_equal 9223372036854775807, @@coll.find_one()["x"]
694
+ end
695
+
696
+ def test_find_by_oid
697
+ @@coll.remove
698
+
699
+ @@coll.save("hello" => "mike")
700
+ id = @@coll.save("hello" => "world")
701
+ assert_kind_of ObjectId, id
702
+
703
+ assert_equal "world", @@coll.find_one(:_id => id)["hello"]
704
+ @@coll.find(:_id => id).to_a.each do |doc|
705
+ assert_equal "world", doc["hello"]
706
+ end
707
+
708
+ id = ObjectId.from_string(id.to_s)
709
+ assert_equal "world", @@coll.find_one(:_id => id)["hello"]
710
+ end
711
+
712
+ def test_save_with_object_that_has_id_but_does_not_actually_exist_in_collection
713
+ @@coll.remove
714
+
715
+ a = {'_id' => '1', 'hello' => 'world'}
716
+ @@coll.save(a)
717
+ assert_equal(1, @@coll.count)
718
+ assert_equal("world", @@coll.find_one()["hello"])
719
+
720
+ a["hello"] = "mike"
721
+ @@coll.save(a)
722
+ assert_equal(1, @@coll.count)
723
+ assert_equal("mike", @@coll.find_one()["hello"])
724
+ end
725
+
726
+ def test_collection_names_errors
727
+ assert_raise TypeError do
728
+ @@db.collection(5)
729
+ end
730
+ assert_raise Mongo::InvalidNSName do
731
+ @@db.collection("")
732
+ end
733
+ assert_raise Mongo::InvalidNSName do
734
+ @@db.collection("te$t")
735
+ end
736
+ assert_raise Mongo::InvalidNSName do
737
+ @@db.collection(".test")
738
+ end
739
+ assert_raise Mongo::InvalidNSName do
740
+ @@db.collection("test.")
741
+ end
742
+ assert_raise Mongo::InvalidNSName do
743
+ @@db.collection("tes..t")
744
+ end
745
+ end
746
+
747
+ def test_rename_collection
748
+ @@db.drop_collection("foo")
749
+ @@db.drop_collection("bar")
750
+ a = @@db.collection("foo")
751
+ b = @@db.collection("bar")
752
+
753
+ assert_raise TypeError do
754
+ a.rename(5)
755
+ end
756
+ assert_raise Mongo::InvalidNSName do
757
+ a.rename("")
758
+ end
759
+ assert_raise Mongo::InvalidNSName do
760
+ a.rename("te$t")
761
+ end
762
+ assert_raise Mongo::InvalidNSName do
763
+ a.rename(".test")
764
+ end
765
+ assert_raise Mongo::InvalidNSName do
766
+ a.rename("test.")
767
+ end
768
+ assert_raise Mongo::InvalidNSName do
769
+ a.rename("tes..t")
770
+ end
771
+
772
+ assert_equal 0, a.count()
773
+ assert_equal 0, b.count()
774
+
775
+ a.insert("x" => 1)
776
+ a.insert("x" => 2)
777
+
778
+ assert_equal 2, a.count()
779
+
780
+ a.rename("bar")
781
+
782
+ assert_equal 2, a.count()
783
+ end
784
+
785
+ # doesn't really test functionality, just that the option is set correctly
786
+ def test_snapshot
787
+ @@db.collection("test").find({}, :snapshot => true).to_a
788
+ assert_raise OperationFailure do
789
+ @@db.collection("test").find({}, :snapshot => true, :sort => 'a').to_a
790
+ end
791
+ end
792
+
793
+ def test_encodings
794
+ if RUBY_VERSION >= '1.9'
795
+ default = "hello world"
796
+ utf8 = "hello world".encode("UTF-8")
797
+ iso8859 = "hello world".encode("ISO-8859-1")
798
+
799
+ if RUBY_PLATFORM =~ /jruby/
800
+ assert_equal "ASCII-8BIT", default.encoding.name
801
+ elsif RUBY_VERSION >= '2.0'
802
+ assert_equal "UTF-8", default.encoding.name
803
+ else
804
+ assert_equal "US-ASCII", default.encoding.name
805
+ end
806
+
807
+ assert_equal "UTF-8", utf8.encoding.name
808
+ assert_equal "ISO-8859-1", iso8859.encoding.name
809
+
810
+ @@coll.remove
811
+ @@coll.save("default" => default, "utf8" => utf8, "iso8859" => iso8859)
812
+ doc = @@coll.find_one()
813
+
814
+ assert_equal "UTF-8", doc["default"].encoding.name
815
+ assert_equal "UTF-8", doc["utf8"].encoding.name
816
+ assert_equal "UTF-8", doc["iso8859"].encoding.name
817
+ end
818
+ end
819
+ end