mongo 1.3.0 → 1.12.5

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 (185) hide show
  1. checksums.yaml +7 -0
  2. checksums.yaml.gz.sig +0 -0
  3. data/{LICENSE.txt → LICENSE} +1 -1
  4. data/README.md +122 -271
  5. data/Rakefile +25 -209
  6. data/VERSION +1 -0
  7. data/bin/mongo_console +31 -9
  8. data/lib/mongo/bulk_write_collection_view.rb +387 -0
  9. data/lib/mongo/collection.rb +576 -269
  10. data/lib/mongo/collection_writer.rb +364 -0
  11. data/lib/mongo/connection/node.rb +249 -0
  12. data/lib/mongo/connection/pool.rb +340 -0
  13. data/lib/mongo/connection/pool_manager.rb +320 -0
  14. data/lib/mongo/connection/sharding_pool_manager.rb +67 -0
  15. data/lib/mongo/connection/socket/socket_util.rb +37 -0
  16. data/lib/mongo/connection/socket/ssl_socket.rb +95 -0
  17. data/lib/mongo/connection/socket/tcp_socket.rb +87 -0
  18. data/lib/mongo/connection/socket/unix_socket.rb +39 -0
  19. data/lib/mongo/connection/socket.rb +18 -0
  20. data/lib/mongo/connection.rb +7 -875
  21. data/lib/mongo/cursor.rb +403 -117
  22. data/lib/mongo/db.rb +444 -243
  23. data/lib/mongo/exception.rb +145 -0
  24. data/lib/mongo/functional/authentication.rb +455 -0
  25. data/lib/mongo/functional/logging.rb +85 -0
  26. data/lib/mongo/functional/read_preference.rb +183 -0
  27. data/lib/mongo/functional/scram.rb +556 -0
  28. data/lib/mongo/functional/uri_parser.rb +409 -0
  29. data/lib/mongo/functional/write_concern.rb +66 -0
  30. data/lib/mongo/functional.rb +20 -0
  31. data/lib/mongo/gridfs/grid.rb +30 -24
  32. data/lib/mongo/gridfs/grid_ext.rb +6 -10
  33. data/lib/mongo/gridfs/grid_file_system.rb +38 -20
  34. data/lib/mongo/gridfs/grid_io.rb +84 -75
  35. data/lib/mongo/gridfs.rb +18 -0
  36. data/lib/mongo/legacy.rb +140 -0
  37. data/lib/mongo/mongo_client.rb +697 -0
  38. data/lib/mongo/mongo_replica_set_client.rb +535 -0
  39. data/lib/mongo/mongo_sharded_client.rb +159 -0
  40. data/lib/mongo/networking.rb +372 -0
  41. data/lib/mongo/{util → utils}/conversions.rb +29 -8
  42. data/lib/mongo/{util → utils}/core_ext.rb +28 -18
  43. data/lib/mongo/{util → utils}/server_version.rb +4 -6
  44. data/lib/mongo/{util → utils}/support.rb +29 -31
  45. data/lib/mongo/utils/thread_local_variable_manager.rb +25 -0
  46. data/lib/mongo/utils.rb +19 -0
  47. data/lib/mongo.rb +51 -50
  48. data/mongo.gemspec +29 -32
  49. data/test/functional/authentication_test.rb +39 -0
  50. data/test/functional/bulk_api_stress_test.rb +133 -0
  51. data/test/functional/bulk_write_collection_view_test.rb +1198 -0
  52. data/test/functional/client_test.rb +627 -0
  53. data/test/functional/collection_test.rb +2175 -0
  54. data/test/functional/collection_writer_test.rb +83 -0
  55. data/test/{conversions_test.rb → functional/conversions_test.rb} +47 -3
  56. data/test/functional/cursor_fail_test.rb +57 -0
  57. data/test/functional/cursor_message_test.rb +56 -0
  58. data/test/functional/cursor_test.rb +683 -0
  59. data/test/functional/db_api_test.rb +835 -0
  60. data/test/functional/db_connection_test.rb +25 -0
  61. data/test/functional/db_test.rb +348 -0
  62. data/test/functional/grid_file_system_test.rb +285 -0
  63. data/test/{grid_io_test.rb → functional/grid_io_test.rb} +72 -11
  64. data/test/{grid_test.rb → functional/grid_test.rb} +88 -15
  65. data/test/functional/pool_test.rb +136 -0
  66. data/test/functional/safe_test.rb +98 -0
  67. data/test/functional/ssl_test.rb +29 -0
  68. data/test/functional/support_test.rb +62 -0
  69. data/test/functional/timeout_test.rb +60 -0
  70. data/test/functional/uri_test.rb +446 -0
  71. data/test/functional/write_concern_test.rb +118 -0
  72. data/test/helpers/general.rb +50 -0
  73. data/test/helpers/test_unit.rb +476 -0
  74. data/test/replica_set/authentication_test.rb +37 -0
  75. data/test/replica_set/basic_test.rb +189 -0
  76. data/test/replica_set/client_test.rb +393 -0
  77. data/test/replica_set/connection_test.rb +138 -0
  78. data/test/replica_set/count_test.rb +66 -0
  79. data/test/replica_set/cursor_test.rb +220 -0
  80. data/test/replica_set/insert_test.rb +157 -0
  81. data/test/replica_set/max_values_test.rb +151 -0
  82. data/test/replica_set/pinning_test.rb +105 -0
  83. data/test/replica_set/query_test.rb +73 -0
  84. data/test/replica_set/read_preference_test.rb +219 -0
  85. data/test/replica_set/refresh_test.rb +211 -0
  86. data/test/replica_set/replication_ack_test.rb +95 -0
  87. data/test/replica_set/ssl_test.rb +32 -0
  88. data/test/sharded_cluster/basic_test.rb +203 -0
  89. data/test/shared/authentication/basic_auth_shared.rb +260 -0
  90. data/test/shared/authentication/bulk_api_auth_shared.rb +249 -0
  91. data/test/shared/authentication/gssapi_shared.rb +176 -0
  92. data/test/shared/authentication/sasl_plain_shared.rb +96 -0
  93. data/test/shared/authentication/scram_shared.rb +92 -0
  94. data/test/shared/ssl_shared.rb +235 -0
  95. data/test/test_helper.rb +53 -94
  96. data/test/threading/basic_test.rb +120 -0
  97. data/test/tools/mongo_config.rb +708 -0
  98. data/test/tools/mongo_config_test.rb +160 -0
  99. data/test/unit/client_test.rb +381 -0
  100. data/test/unit/collection_test.rb +89 -53
  101. data/test/unit/connection_test.rb +282 -32
  102. data/test/unit/cursor_test.rb +206 -8
  103. data/test/unit/db_test.rb +55 -13
  104. data/test/unit/grid_test.rb +43 -16
  105. data/test/unit/mongo_sharded_client_test.rb +48 -0
  106. data/test/unit/node_test.rb +93 -0
  107. data/test/unit/pool_manager_test.rb +111 -0
  108. data/test/unit/read_pref_test.rb +406 -0
  109. data/test/unit/read_test.rb +159 -0
  110. data/test/unit/safe_test.rb +69 -36
  111. data/test/unit/sharding_pool_manager_test.rb +84 -0
  112. data/test/unit/write_concern_test.rb +175 -0
  113. data.tar.gz.sig +3 -0
  114. metadata +227 -216
  115. metadata.gz.sig +0 -0
  116. data/docs/CREDITS.md +0 -123
  117. data/docs/FAQ.md +0 -116
  118. data/docs/GridFS.md +0 -158
  119. data/docs/HISTORY.md +0 -244
  120. data/docs/RELEASES.md +0 -33
  121. data/docs/REPLICA_SETS.md +0 -72
  122. data/docs/TUTORIAL.md +0 -247
  123. data/docs/WRITE_CONCERN.md +0 -28
  124. data/lib/mongo/exceptions.rb +0 -71
  125. data/lib/mongo/gridfs/grid_io_fix.rb +0 -38
  126. data/lib/mongo/repl_set_connection.rb +0 -342
  127. data/lib/mongo/test.rb +0 -20
  128. data/lib/mongo/util/pool.rb +0 -177
  129. data/lib/mongo/util/uri_parser.rb +0 -185
  130. data/test/async/collection_test.rb +0 -224
  131. data/test/async/connection_test.rb +0 -24
  132. data/test/async/cursor_test.rb +0 -162
  133. data/test/async/worker_pool_test.rb +0 -99
  134. data/test/auxillary/1.4_features.rb +0 -166
  135. data/test/auxillary/authentication_test.rb +0 -68
  136. data/test/auxillary/autoreconnect_test.rb +0 -41
  137. data/test/auxillary/fork_test.rb +0 -30
  138. data/test/auxillary/repl_set_auth_test.rb +0 -58
  139. data/test/auxillary/slave_connection_test.rb +0 -36
  140. data/test/auxillary/threaded_authentication_test.rb +0 -101
  141. data/test/bson/binary_test.rb +0 -15
  142. data/test/bson/bson_test.rb +0 -649
  143. data/test/bson/byte_buffer_test.rb +0 -208
  144. data/test/bson/hash_with_indifferent_access_test.rb +0 -38
  145. data/test/bson/json_test.rb +0 -17
  146. data/test/bson/object_id_test.rb +0 -154
  147. data/test/bson/ordered_hash_test.rb +0 -204
  148. data/test/bson/timestamp_test.rb +0 -24
  149. data/test/collection_test.rb +0 -910
  150. data/test/connection_test.rb +0 -309
  151. data/test/cursor_fail_test.rb +0 -75
  152. data/test/cursor_message_test.rb +0 -43
  153. data/test/cursor_test.rb +0 -483
  154. data/test/db_api_test.rb +0 -726
  155. data/test/db_connection_test.rb +0 -15
  156. data/test/db_test.rb +0 -287
  157. data/test/grid_file_system_test.rb +0 -243
  158. data/test/load/resque/load.rb +0 -21
  159. data/test/load/resque/processor.rb +0 -26
  160. data/test/load/thin/load.rb +0 -24
  161. data/test/load/unicorn/load.rb +0 -23
  162. data/test/load/unicorn/unicorn.rb +0 -29
  163. data/test/replica_sets/connect_test.rb +0 -94
  164. data/test/replica_sets/connection_string_test.rb +0 -32
  165. data/test/replica_sets/count_test.rb +0 -35
  166. data/test/replica_sets/insert_test.rb +0 -53
  167. data/test/replica_sets/pooled_insert_test.rb +0 -55
  168. data/test/replica_sets/query_secondaries.rb +0 -96
  169. data/test/replica_sets/query_test.rb +0 -51
  170. data/test/replica_sets/replication_ack_test.rb +0 -66
  171. data/test/replica_sets/rs_test_helper.rb +0 -27
  172. data/test/safe_test.rb +0 -68
  173. data/test/support/hash_with_indifferent_access.rb +0 -186
  174. data/test/support/keys.rb +0 -45
  175. data/test/support_test.rb +0 -18
  176. data/test/threading/threading_with_large_pool_test.rb +0 -90
  177. data/test/threading_test.rb +0 -87
  178. data/test/tools/auth_repl_set_manager.rb +0 -14
  179. data/test/tools/load.rb +0 -58
  180. data/test/tools/repl_set_manager.rb +0 -266
  181. data/test/tools/sharding_manager.rb +0 -202
  182. data/test/tools/test.rb +0 -4
  183. data/test/unit/pool_test.rb +0 -9
  184. data/test/unit/repl_set_connection_test.rb +0 -59
  185. data/test/uri_test.rb +0 -91
@@ -1,910 +0,0 @@
1
- require './test/test_helper'
2
-
3
- class TestCollection < Test::Unit::TestCase
4
- @@connection ||= standard_connection(:op_timeout => 2)
5
- @@db = @@connection.db(MONGO_TEST_DB)
6
- @@test = @@db.collection("test")
7
- @@version = @@connection.server_version
8
-
9
- def setup
10
- @@test.remove
11
- end
12
-
13
- def test_optional_pk_factory
14
- @coll_default_pk = @@db.collection('stuff')
15
- assert_equal BSON::ObjectId, @coll_default_pk.pk_factory
16
- @coll_default_pk = @@db.create_collection('more-stuff')
17
- assert_equal BSON::ObjectId, @coll_default_pk.pk_factory
18
-
19
- # Create a db with a pk_factory.
20
- @db = Connection.new(ENV['MONGO_RUBY_DRIVER_HOST'] || 'localhost',
21
- ENV['MONGO_RUBY_DRIVER_PORT'] || Connection::DEFAULT_PORT).db(MONGO_TEST_DB, :pk => Object.new)
22
- @coll = @db.collection('coll-with-pk')
23
- assert @coll.pk_factory.is_a?(Object)
24
-
25
- @coll = @db.create_collection('created_coll_with_pk')
26
- assert @coll.pk_factory.is_a?(Object)
27
- end
28
-
29
- class TestPK
30
- def self.create_pk
31
- end
32
- end
33
-
34
- def test_pk_factory_on_collection
35
- @coll = Collection.new('foo', @@db, TestPK)
36
- assert_equal TestPK, @coll.pk_factory
37
-
38
-
39
- @coll2 = Collection.new('foo', @@db, :pk => TestPK)
40
- assert_equal TestPK, @coll2.pk_factory
41
- end
42
-
43
- def test_valid_names
44
- assert_raise Mongo::InvalidNSName do
45
- @@db["te$t"]
46
- end
47
-
48
- assert_raise Mongo::InvalidNSName do
49
- @@db['$main']
50
- end
51
-
52
- assert @@db['$cmd']
53
- assert @@db['oplog.$main']
54
- end
55
-
56
- def test_collection
57
- assert_kind_of Collection, @@db["test"]
58
- assert_equal @@db["test"].name(), @@db.collection("test").name()
59
- assert_equal @@db["test"].name(), @@db[:test].name()
60
-
61
- assert_kind_of Collection, @@db["test"]["foo"]
62
- assert_equal @@db["test"]["foo"].name(), @@db.collection("test.foo").name()
63
- assert_equal @@db["test"]["foo"].name(), @@db["test.foo"].name()
64
-
65
- @@db["test"]["foo"].remove
66
- @@db["test"]["foo"].insert("x" => 5)
67
- assert_equal 5, @@db.collection("test.foo").find_one()["x"]
68
- end
69
-
70
- def test_rename_collection
71
- @@db.drop_collection('foo1')
72
- @@db.drop_collection('bar1')
73
-
74
- @col = @@db.create_collection('foo1')
75
- assert_equal 'foo1', @col.name
76
-
77
- @col.rename('bar1')
78
- assert_equal 'bar1', @col.name
79
- end
80
-
81
- def test_nil_id
82
- assert_equal 5, @@test.insert({"_id" => 5, "foo" => "bar"}, {:safe => true})
83
- assert_equal 5, @@test.save({"_id" => 5, "foo" => "baz"}, {:safe => true})
84
- assert_equal nil, @@test.find_one("foo" => "bar")
85
- assert_equal "baz", @@test.find_one(:_id => 5)["foo"]
86
- assert_raise OperationFailure do
87
- @@test.insert({"_id" => 5, "foo" => "bar"}, {:safe => true})
88
- end
89
-
90
- assert_equal nil, @@test.insert({"_id" => nil, "foo" => "bar"}, {:safe => true})
91
- assert_equal nil, @@test.save({"_id" => nil, "foo" => "baz"}, {:safe => true})
92
- assert_equal nil, @@test.find_one("foo" => "bar")
93
- assert_equal "baz", @@test.find_one(:_id => nil)["foo"]
94
- assert_raise OperationFailure do
95
- @@test.insert({"_id" => nil, "foo" => "bar"}, {:safe => true})
96
- end
97
- assert_raise OperationFailure do
98
- @@test.insert({:_id => nil, "foo" => "bar"}, {:safe => true})
99
- end
100
- end
101
-
102
- if @@version > "1.1"
103
- def setup_for_distinct
104
- @@test.remove
105
- @@test.insert([{:a => 0, :b => {:c => "a"}},
106
- {:a => 1, :b => {:c => "b"}},
107
- {:a => 1, :b => {:c => "c"}},
108
- {:a => 2, :b => {:c => "a"}},
109
- {:a => 3},
110
- {:a => 3}])
111
- end
112
-
113
- def test_distinct_queries
114
- setup_for_distinct
115
- assert_equal [0, 1, 2, 3], @@test.distinct(:a).sort
116
- assert_equal ["a", "b", "c"], @@test.distinct("b.c").sort
117
- end
118
-
119
- if @@version >= "1.2"
120
- def test_filter_collection_with_query
121
- setup_for_distinct
122
- assert_equal [2, 3], @@test.distinct(:a, {:a => {"$gt" => 1}}).sort
123
- end
124
-
125
- def test_filter_nested_objects
126
- setup_for_distinct
127
- assert_equal ["a", "b"], @@test.distinct("b.c", {"b.c" => {"$ne" => "c"}}).sort
128
- end
129
- end
130
- end
131
-
132
- def test_safe_insert
133
- @@test.create_index("hello", :unique => true)
134
- a = {"hello" => "world"}
135
- @@test.insert(a)
136
- @@test.insert(a)
137
- assert(@@db.get_last_error['err'].include?("11000"))
138
-
139
- assert_raise OperationFailure do
140
- @@test.insert(a, :safe => true)
141
- end
142
- end
143
-
144
- def test_maximum_insert_size
145
- docs = []
146
- 16.times do
147
- docs << {'foo' => 'a' * 1_000_000}
148
- end
149
-
150
- assert_raise InvalidOperation do
151
- @@test.insert(docs)
152
- end
153
- end
154
-
155
- if @@version >= "1.5.1"
156
- def test_safe_mode_with_advanced_safe_with_invalid_options
157
- assert_raise_error ArgumentError, "Unknown key(s): wtime" do
158
- @@test.insert({:foo => 1}, :safe => {:w => 2, :wtime => 1, :fsync => true})
159
- end
160
- assert_raise_error ArgumentError, "Unknown key(s): wtime" do
161
- @@test.update({:foo => 1}, {:foo => 2}, :safe => {:w => 2, :wtime => 1, :fsync => true})
162
- end
163
-
164
- assert_raise_error ArgumentError, "Unknown key(s): wtime" do
165
- @@test.remove({:foo => 2}, :safe => {:w => 2, :wtime => 1, :fsync => true})
166
- end
167
- end
168
- end
169
-
170
- def test_update
171
- id1 = @@test.save("x" => 5)
172
- @@test.update({}, {"$inc" => {"x" => 1}})
173
- assert_equal 1, @@test.count()
174
- assert_equal 6, @@test.find_one(:_id => id1)["x"]
175
-
176
- id2 = @@test.save("x" => 1)
177
- @@test.update({"x" => 6}, {"$inc" => {"x" => 1}})
178
- assert_equal 7, @@test.find_one(:_id => id1)["x"]
179
- assert_equal 1, @@test.find_one(:_id => id2)["x"]
180
- end
181
-
182
- if @@version >= "1.1.3"
183
- def test_multi_update
184
- @@test.save("num" => 10)
185
- @@test.save("num" => 10)
186
- @@test.save("num" => 10)
187
- assert_equal 3, @@test.count
188
-
189
- @@test.update({"num" => 10}, {"$set" => {"num" => 100}}, :multi => true)
190
- @@test.find.each do |doc|
191
- assert_equal 100, doc["num"]
192
- end
193
- end
194
- end
195
-
196
- def test_upsert
197
- @@test.update({"page" => "/"}, {"$inc" => {"count" => 1}}, :upsert => true)
198
- @@test.update({"page" => "/"}, {"$inc" => {"count" => 1}}, :upsert => true)
199
-
200
- assert_equal 1, @@test.count()
201
- assert_equal 2, @@test.find_one()["count"]
202
- end
203
-
204
- if @@version < "1.1.3"
205
- def test_safe_update
206
- @@test.create_index("x")
207
- @@test.insert("x" => 5)
208
-
209
- @@test.update({}, {"$inc" => {"x" => 1}})
210
- assert @@db.error?
211
-
212
- # Can't change an index.
213
- assert_raise OperationFailure do
214
- @@test.update({}, {"$inc" => {"x" => 1}}, :safe => true)
215
- end
216
- @@test.drop
217
- end
218
- else
219
- def test_safe_update
220
- @@test.create_index("x", :unique => true)
221
- @@test.insert("x" => 5)
222
- @@test.insert("x" => 10)
223
-
224
- # Can update an indexed collection.
225
- @@test.update({}, {"$inc" => {"x" => 1}})
226
- assert !@@db.error?
227
-
228
- # Can't duplicate an index.
229
- assert_raise OperationFailure do
230
- @@test.update({}, {"x" => 10}, :safe => true)
231
- end
232
- @@test.drop
233
- end
234
- end
235
-
236
- def test_safe_save
237
- @@test.create_index("hello", :unique => true)
238
-
239
- @@test.save("hello" => "world")
240
- @@test.save("hello" => "world")
241
-
242
- assert_raise OperationFailure do
243
- @@test.save({"hello" => "world"}, :safe => true)
244
- end
245
- @@test.drop
246
- end
247
-
248
- def test_mocked_safe_remove
249
- @conn = standard_connection
250
- @db = @conn[MONGO_TEST_DB]
251
- @test = @db['test-safe-remove']
252
- @test.save({:a => 20})
253
- @conn.stubs(:receive).returns([[{'ok' => 0, 'err' => 'failed'}], 1, 0])
254
-
255
- assert_raise OperationFailure do
256
- @test.remove({}, :safe => true)
257
- end
258
- @test.drop
259
- end
260
-
261
- def test_safe_remove
262
- @conn = standard_connection
263
- @db = @conn[MONGO_TEST_DB]
264
- @test = @db['test-safe-remove']
265
- @test.save({:a => 50})
266
- assert_equal 1, @test.remove({}, :safe => true)["n"]
267
- @test.drop
268
- end
269
-
270
- def test_remove_return_value
271
- assert_equal true, @@test.remove({})
272
- end
273
-
274
- def test_count
275
- @@test.drop
276
-
277
- assert_equal 0, @@test.count
278
- @@test.save("x" => 1)
279
- @@test.save("x" => 2)
280
- assert_equal 2, @@test.count
281
- end
282
-
283
- # Note: #size is just an alias for #count.
284
- def test_size
285
- @@test.drop
286
-
287
- assert_equal 0, @@test.count
288
- assert_equal @@test.size, @@test.count
289
- @@test.save("x" => 1)
290
- @@test.save("x" => 2)
291
- assert_equal @@test.size, @@test.count
292
- end
293
-
294
- def test_no_timeout_option
295
- @@test.drop
296
-
297
- assert_raise ArgumentError, "Timeout can be set to false only when #find is invoked with a block." do
298
- @@test.find({}, :timeout => false)
299
- end
300
-
301
- @@test.find({}, :timeout => false) do |cursor|
302
- assert_equal 0, cursor.count
303
- end
304
-
305
- @@test.save("x" => 1)
306
- @@test.save("x" => 2)
307
- @@test.find({}, :timeout => false) do |cursor|
308
- assert_equal 2, cursor.count
309
- end
310
- end
311
-
312
- def test_defualt_timeout
313
- cursor = @@test.find
314
- assert_equal true, cursor.timeout
315
- end
316
-
317
- def test_fields_as_hash
318
- @@test.save(:a => 1, :b => 1, :c => 1)
319
-
320
- doc = @@test.find_one({:a => 1}, :fields => {:b => 0})
321
- assert_nil doc['b']
322
- assert doc['a']
323
- assert doc['c']
324
-
325
- doc = @@test.find_one({:a => 1}, :fields => {:a => 1, :b => 1})
326
- assert_nil doc['c']
327
- assert doc['a']
328
- assert doc['b']
329
-
330
-
331
- assert_raise Mongo::OperationFailure do
332
- @@test.find_one({:a => 1}, :fields => {:a => 1, :b => 0})
333
- end
334
- end
335
-
336
- if @@version >= "1.5.1"
337
- def test_fields_with_slice
338
- @@test.save({:foo => [1, 2, 3, 4, 5, 6], :test => 'slice'})
339
-
340
- doc = @@test.find_one({:test => 'slice'}, :fields => {'foo' => {'$slice' => [0, 3]}})
341
- assert_equal [1, 2, 3], doc['foo']
342
- @@test.remove
343
- end
344
- end
345
-
346
- def test_find_one
347
- id = @@test.save("hello" => "world", "foo" => "bar")
348
-
349
- assert_equal "world", @@test.find_one()["hello"]
350
- assert_equal @@test.find_one(id), @@test.find_one()
351
- assert_equal @@test.find_one(nil), @@test.find_one()
352
- assert_equal @@test.find_one({}), @@test.find_one()
353
- assert_equal @@test.find_one("hello" => "world"), @@test.find_one()
354
- assert_equal @@test.find_one(BSON::OrderedHash["hello", "world"]), @@test.find_one()
355
-
356
- assert @@test.find_one(nil, :fields => ["hello"]).include?("hello")
357
- assert !@@test.find_one(nil, :fields => ["foo"]).include?("hello")
358
- assert_equal ["_id"], @@test.find_one(nil, :fields => []).keys()
359
-
360
- assert_equal nil, @@test.find_one("hello" => "foo")
361
- assert_equal nil, @@test.find_one(BSON::OrderedHash["hello", "foo"])
362
- assert_equal nil, @@test.find_one(ObjectId.new)
363
-
364
- assert_raise TypeError do
365
- @@test.find_one(6)
366
- end
367
- end
368
-
369
- def test_insert_adds_id
370
- doc = {"hello" => "world"}
371
- @@test.insert(doc)
372
- assert(doc.include?(:_id))
373
-
374
- docs = [{"hello" => "world"}, {"hello" => "world"}]
375
- @@test.insert(docs)
376
- docs.each do |d|
377
- assert(d.include?(:_id))
378
- end
379
- end
380
-
381
- def test_save_adds_id
382
- doc = {"hello" => "world"}
383
- @@test.save(doc)
384
- assert(doc.include?(:_id))
385
- end
386
-
387
- def test_optional_find_block
388
- 10.times do |i|
389
- @@test.save("i" => i)
390
- end
391
-
392
- x = nil
393
- @@test.find("i" => 2) { |cursor|
394
- x = cursor.count()
395
- }
396
- assert_equal 1, x
397
-
398
- i = 0
399
- @@test.find({}, :skip => 5) do |cursor|
400
- cursor.each do |doc|
401
- i = i + 1
402
- end
403
- end
404
- assert_equal 5, i
405
-
406
- c = nil
407
- @@test.find() do |cursor|
408
- c = cursor
409
- end
410
- assert c.closed?
411
- end
412
-
413
- if @@version > "1.1.1"
414
- def test_map_reduce
415
- @@test << { "user_id" => 1 }
416
- @@test << { "user_id" => 2 }
417
-
418
- m = "function() { emit(this.user_id, 1); }"
419
- r = "function(k,vals) { return 1; }"
420
- res = @@test.map_reduce(m, r, :out => 'foo');
421
- assert res.find_one({"_id" => 1})
422
- assert res.find_one({"_id" => 2})
423
- end
424
-
425
- def test_map_reduce_with_code_objects
426
- @@test << { "user_id" => 1 }
427
- @@test << { "user_id" => 2 }
428
-
429
- m = Code.new("function() { emit(this.user_id, 1); }")
430
- r = Code.new("function(k,vals) { return 1; }")
431
- res = @@test.map_reduce(m, r, :out => 'foo');
432
- assert res.find_one({"_id" => 1})
433
- assert res.find_one({"_id" => 2})
434
- end
435
-
436
- def test_map_reduce_with_options
437
- @@test.remove
438
- @@test << { "user_id" => 1 }
439
- @@test << { "user_id" => 2 }
440
- @@test << { "user_id" => 3 }
441
-
442
- m = Code.new("function() { emit(this.user_id, 1); }")
443
- r = Code.new("function(k,vals) { return 1; }")
444
- res = @@test.map_reduce(m, r, :query => {"user_id" => {"$gt" => 1}}, :out => 'foo');
445
- assert_equal 2, res.count
446
- assert res.find_one({"_id" => 2})
447
- assert res.find_one({"_id" => 3})
448
- end
449
-
450
- def test_map_reduce_with_raw_response
451
- m = Code.new("function() { emit(this.user_id, 1); }")
452
- r = Code.new("function(k,vals) { return 1; }")
453
- res = @@test.map_reduce(m, r, :raw => true, :out => 'foo')
454
- assert res["result"]
455
- assert res["counts"]
456
- assert res["timeMillis"]
457
- end
458
-
459
- def test_map_reduce_with_output_collection
460
- output_collection = "test-map-coll"
461
- m = Code.new("function() { emit(this.user_id, 1); }")
462
- r = Code.new("function(k,vals) { return 1; }")
463
- res = @@test.map_reduce(m, r, :raw => true, :out => output_collection)
464
- assert_equal output_collection, res["result"]
465
- assert res["counts"]
466
- assert res["timeMillis"]
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
498
- end
499
-
500
- if @@version > "1.3.0"
501
- def test_find_and_modify
502
- @@test << { :a => 1, :processed => false }
503
- @@test << { :a => 2, :processed => false }
504
- @@test << { :a => 3, :processed => false }
505
-
506
- @@test.find_and_modify(:query => {}, :sort => [['a', -1]], :update => {"$set" => {:processed => true}})
507
-
508
- assert @@test.find_one({:a => 3})['processed']
509
- end
510
-
511
- def test_find_and_modify_with_invalid_options
512
- @@test << { :a => 1, :processed => false }
513
- @@test << { :a => 2, :processed => false }
514
- @@test << { :a => 3, :processed => false }
515
-
516
- assert_raise Mongo::OperationFailure do
517
- @@test.find_and_modify(:blimey => {})
518
- end
519
- end
520
- end
521
-
522
- if @@version >= "1.3.5"
523
- def test_coll_stats
524
- @@test << {:n => 1}
525
- @@test.create_index("n")
526
-
527
- assert_equal "#{MONGO_TEST_DB}.test", @@test.stats['ns']
528
- end
529
- end
530
-
531
- def test_saving_dates_pre_epoch
532
- begin
533
- @@test.save({'date' => Time.utc(1600)})
534
- assert_in_delta Time.utc(1600), @@test.find_one()["date"], 2
535
- rescue ArgumentError
536
- # See note in test_date_before_epoch (BSONTest)
537
- end
538
- end
539
-
540
- def test_save_symbol_find_string
541
- @@test.save(:foo => :mike)
542
-
543
- assert_equal :mike, @@test.find_one(:foo => :mike)["foo"]
544
- assert_equal :mike, @@test.find_one("foo" => :mike)["foo"]
545
-
546
- # TODO enable these tests conditionally based on server version (if >1.0)
547
- # assert_equal :mike, @@test.find_one(:foo => "mike")["foo"]
548
- # assert_equal :mike, @@test.find_one("foo" => "mike")["foo"]
549
- end
550
-
551
- def test_limit_and_skip
552
- 10.times do |i|
553
- @@test.save(:foo => i)
554
- end
555
-
556
- assert_equal 5, @@test.find({}, :skip => 5).next_document()["foo"]
557
- assert_equal nil, @@test.find({}, :skip => 10).next_document()
558
-
559
- assert_equal 5, @@test.find({}, :limit => 5).to_a.length
560
-
561
- assert_equal 3, @@test.find({}, :skip => 3, :limit => 5).next_document()["foo"]
562
- assert_equal 5, @@test.find({}, :skip => 3, :limit => 5).to_a.length
563
- end
564
-
565
- def test_large_limit
566
- 2000.times do |i|
567
- @@test.insert("x" => i, "y" => "mongomongo" * 1000)
568
- end
569
-
570
- assert_equal 2000, @@test.count
571
-
572
- i = 0
573
- y = 0
574
- @@test.find({}, :limit => 1900).each do |doc|
575
- i += 1
576
- y += doc["x"]
577
- end
578
-
579
- assert_equal 1900, i
580
- assert_equal 1804050, y
581
- end
582
-
583
- def test_small_limit
584
- @@test.insert("x" => "hello world")
585
- @@test.insert("x" => "goodbye world")
586
-
587
- assert_equal 2, @@test.count
588
-
589
- x = 0
590
- @@test.find({}, :limit => 1).each do |doc|
591
- x += 1
592
- assert_equal "hello world", doc["x"]
593
- end
594
-
595
- assert_equal 1, x
596
- end
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
612
-
613
- def test_ensure_index
614
- @@test.drop_indexes
615
- @@test.insert("x" => "hello world")
616
- assert_equal 1, @@test.index_information.keys.count #default index
617
-
618
- @@test.ensure_index([["x", Mongo::DESCENDING]], {})
619
- assert_equal 2, @@test.index_information.keys.count
620
- assert @@test.index_information.keys.include? "x_-1"
621
-
622
- @@test.ensure_index([["x", Mongo::ASCENDING]])
623
- assert @@test.index_information.keys.include? "x_1"
624
-
625
- @@test.ensure_index([["type", 1], ["date", -1]])
626
- assert @@test.index_information.keys.include? "type_1_date_-1"
627
-
628
- @@test.drop_index("x_1")
629
- assert_equal 3, @@test.index_information.keys.count
630
- @@test.drop_index("x_-1")
631
- assert_equal 2, @@test.index_information.keys.count
632
-
633
- @@test.ensure_index([["x", Mongo::DESCENDING]], {})
634
- assert_equal 3, @@test.index_information.keys.count
635
- assert @@test.index_information.keys.include? "x_-1"
636
-
637
- # Make sure that drop_index expires cache properly
638
- @@test.ensure_index([['a', 1]])
639
- assert @@test.index_information.keys.include?("a_1")
640
- @@test.drop_index("a_1")
641
- assert !@@test.index_information.keys.include?("a_1")
642
- @@test.ensure_index([['a', 1]])
643
- assert @@test.index_information.keys.include?("a_1")
644
- @@test.drop_index("a_1")
645
- end
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
-
664
- context "Grouping" do
665
- setup do
666
- @@test.remove
667
- @@test.save("a" => 1)
668
- @@test.save("b" => 1)
669
- @initial = {"count" => 0}
670
- @reduce_function = "function (obj, prev) { prev.count += inc_value; }"
671
- end
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
-
683
- should "group results using eval form" do
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"]
687
- end
688
-
689
- should "finalize grouped results" do
690
- @finalize = "function(doc) {doc.f = doc.count + 200; }"
691
- assert_equal 202, @@test.group(:initial => @initial, :reduce => Code.new(@reduce_function, {"inc_value" => 1}), :finalize => @finalize)[0]["f"]
692
- end
693
- end
694
-
695
- context "Grouping with key" do
696
- setup do
697
- @@test.remove
698
- @@test.save("a" => 1, "pop" => 100)
699
- @@test.save("a" => 1, "pop" => 100)
700
- @@test.save("a" => 2, "pop" => 100)
701
- @@test.save("a" => 2, "pop" => 100)
702
- @initial = {"count" => 0, "foo" => 1}
703
- @reduce_function = "function (obj, prev) { prev.count += obj.pop; }"
704
- end
705
-
706
- should "group" do
707
- result = @@test.group(:key => :a, :initial => @initial, :reduce => @reduce_function)
708
- assert result.all? { |r| r['count'] == 200 }
709
- end
710
- end
711
-
712
- context "Grouping with a key function" do
713
- setup do
714
- @@test.remove
715
- @@test.save("a" => 1)
716
- @@test.save("a" => 2)
717
- @@test.save("a" => 3)
718
- @@test.save("a" => 4)
719
- @@test.save("a" => 5)
720
- @initial = {"count" => 0}
721
- @keyf = "function (doc) { if(doc.a % 2 == 0) { return {even: true}; } else {return {odd: true}} };"
722
- @reduce = "function (obj, prev) { prev.count += 1; }"
723
- end
724
-
725
- should "group results" do
726
- results = @@test.group(:keyf => @keyf, :initial => @initial, :reduce => @reduce).sort {|a, b| a['count'] <=> b['count']}
727
- assert results[0]['even'] && results[0]['count'] == 2.0
728
- assert results[1]['odd'] && results[1]['count'] == 3.0
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
737
- end
738
-
739
- context "A collection with two records" do
740
- setup do
741
- @collection = @@db.collection('test-collection')
742
- @collection.insert({:name => "Jones"})
743
- @collection.insert({:name => "Smith"})
744
- end
745
-
746
- should "have two records" do
747
- assert_equal 2, @collection.size
748
- end
749
-
750
- should "remove the two records" do
751
- @collection.remove()
752
- assert_equal 0, @collection.size
753
- end
754
-
755
- should "remove all records if an empty document is specified" do
756
- @collection.remove({})
757
- assert_equal 0, @collection.find.count
758
- end
759
-
760
- should "remove only matching records" do
761
- @collection.remove({:name => "Jones"})
762
- assert_equal 1, @collection.size
763
- end
764
- end
765
-
766
- context "Creating indexes " do
767
- setup do
768
- @@db.drop_collection('geo')
769
- @@db.drop_collection('test-collection')
770
- @collection = @@db.collection('test-collection')
771
- @geo = @@db.collection('geo')
772
- end
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
-
785
- should "create a geospatial index" do
786
- @geo.save({'loc' => [-100, 100]})
787
- @geo.create_index([['loc', Mongo::GEO2D]])
788
- assert @geo.index_information['loc_2d']
789
- end
790
-
791
- should "create a unique index" do
792
- @collection.create_index([['a', Mongo::ASCENDING]], :unique => true)
793
- assert @collection.index_information['a_1']['unique'] == true
794
- end
795
-
796
- should "drop duplicates" do
797
- @collection.insert({:a => 1})
798
- @collection.insert({:a => 1})
799
- assert_equal 2, @collection.find({:a => 1}).count
800
- @collection.create_index([['a', Mongo::ASCENDING]], :unique => true, :dropDups => true)
801
- assert_equal 1, @collection.find({:a => 1}).count
802
- end
803
-
804
- should "drop duplicates with ruby-like drop_dups key" do
805
- @collection.insert({:a => 1})
806
- @collection.insert({:a => 1})
807
- assert_equal 2, @collection.find({:a => 1}).count
808
- @collection.create_index([['a', Mongo::ASCENDING]], :unique => true, :drop_dups => true)
809
- assert_equal 1, @collection.find({:a => 1}).count
810
- end
811
-
812
- should "create an index in the background" do
813
- if @@version > '1.3.1'
814
- @collection.create_index([['b', Mongo::ASCENDING]], :background => true)
815
- assert @collection.index_information['b_1']['background'] == true
816
- else
817
- assert true
818
- end
819
- end
820
-
821
- should "require an array of arrays" do
822
- assert_raise MongoArgumentError do
823
- @collection.create_index(['c', Mongo::ASCENDING])
824
- end
825
- end
826
-
827
- should "enforce proper index types" do
828
- assert_raise MongoArgumentError do
829
- @collection.create_index([['c', 'blah']])
830
- end
831
- end
832
-
833
- should "raise an error if index name is greater than 128" do
834
- assert_raise Mongo::OperationFailure do
835
- @collection.create_index([['a' * 25, 1], ['b' * 25, 1],
836
- ['c' * 25, 1], ['d' * 25, 1], ['e' * 25, 1]])
837
- end
838
- end
839
-
840
- should "allow for an alternate name to be specified" do
841
- @collection.create_index([['a' * 25, 1], ['b' * 25, 1],
842
- ['c' * 25, 1], ['d' * 25, 1], ['e' * 25, 1]], :name => 'foo_index')
843
- assert @collection.index_information['foo_index']
844
- end
845
-
846
- should "generate indexes in the proper order" do
847
- @collection.expects(:insert_documents) do |sel, coll, safe|
848
- assert_equal 'b_1_a_1', sel[:name]
849
- end
850
- @collection.create_index([['b', 1], ['a', 1]])
851
- end
852
-
853
- should "allow multiple calls to create_index" do
854
-
855
- end
856
-
857
- should "allow creation of multiple indexes" do
858
- assert @collection.create_index([['a', 1]])
859
- assert @collection.create_index([['a', 1]])
860
- end
861
-
862
- context "with an index created" do
863
- setup do
864
- @collection.create_index([['b', 1], ['a', 1]])
865
- end
866
-
867
- should "return properly ordered index information" do
868
- assert @collection.index_information['b_1_a_1']
869
- end
870
- end
871
- end
872
-
873
- context "Capped collections" do
874
- setup do
875
- @@db.drop_collection('log')
876
- @capped = @@db.create_collection('log', :capped => true, :size => 1024)
877
-
878
- 10.times { |n| @capped.insert({:n => n}) }
879
- end
880
-
881
- should "find using a standard cursor" do
882
- cursor = @capped.find
883
- 10.times do
884
- assert cursor.next_document
885
- end
886
- assert_nil cursor.next_document
887
- @capped.insert({:n => 100})
888
- assert_nil cursor.next_document
889
- end
890
-
891
- should "fail tailable cursor on a non-capped collection" do
892
- col = @@db['regular-collection']
893
- col.insert({:a => 1000})
894
- tail = Cursor.new(col, :tailable => true, :order => [['$natural', 1]])
895
- assert_raise OperationFailure do
896
- tail.next_document
897
- end
898
- end
899
-
900
- should "find using a tailable cursor" do
901
- tail = Cursor.new(@capped, :tailable => true, :order => [['$natural', 1]])
902
- 10.times do
903
- assert tail.next_document
904
- end
905
- assert_nil tail.next_document
906
- @capped.insert({:n => 100})
907
- assert tail.next_document
908
- end
909
- end
910
- end