mongo 1.10.0-java

Sign up to get free protection for your applications and to get access to all the features.
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