pahagon-mongo-abd 0.14.1

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 (81) hide show
  1. data/README.rdoc +353 -0
  2. data/Rakefile +62 -0
  3. data/bin/bson_benchmark.rb +59 -0
  4. data/bin/mongo_console +21 -0
  5. data/bin/run_test_script +19 -0
  6. data/bin/standard_benchmark +109 -0
  7. data/examples/admin.rb +41 -0
  8. data/examples/benchmarks.rb +42 -0
  9. data/examples/blog.rb +76 -0
  10. data/examples/capped.rb +23 -0
  11. data/examples/cursor.rb +47 -0
  12. data/examples/gridfs.rb +87 -0
  13. data/examples/index_test.rb +125 -0
  14. data/examples/info.rb +30 -0
  15. data/examples/queries.rb +69 -0
  16. data/examples/simple.rb +23 -0
  17. data/examples/strict.rb +34 -0
  18. data/examples/types.rb +35 -0
  19. data/lib/mongo.rb +19 -0
  20. data/lib/mongo/admin.rb +83 -0
  21. data/lib/mongo/collection.rb +415 -0
  22. data/lib/mongo/connection.rb +151 -0
  23. data/lib/mongo/cursor.rb +279 -0
  24. data/lib/mongo/db.rb +560 -0
  25. data/lib/mongo/errors.rb +26 -0
  26. data/lib/mongo/gridfs.rb +16 -0
  27. data/lib/mongo/gridfs/chunk.rb +92 -0
  28. data/lib/mongo/gridfs/grid_store.rb +464 -0
  29. data/lib/mongo/message.rb +20 -0
  30. data/lib/mongo/message/get_more_message.rb +32 -0
  31. data/lib/mongo/message/insert_message.rb +37 -0
  32. data/lib/mongo/message/kill_cursors_message.rb +31 -0
  33. data/lib/mongo/message/message.rb +80 -0
  34. data/lib/mongo/message/message_header.rb +45 -0
  35. data/lib/mongo/message/msg_message.rb +29 -0
  36. data/lib/mongo/message/opcodes.rb +27 -0
  37. data/lib/mongo/message/query_message.rb +78 -0
  38. data/lib/mongo/message/remove_message.rb +37 -0
  39. data/lib/mongo/message/update_message.rb +38 -0
  40. data/lib/mongo/query.rb +118 -0
  41. data/lib/mongo/types/binary.rb +38 -0
  42. data/lib/mongo/types/code.rb +30 -0
  43. data/lib/mongo/types/dbref.rb +33 -0
  44. data/lib/mongo/types/objectid.rb +143 -0
  45. data/lib/mongo/types/regexp_of_holding.rb +40 -0
  46. data/lib/mongo/util/bson.rb +546 -0
  47. data/lib/mongo/util/byte_buffer.rb +167 -0
  48. data/lib/mongo/util/ordered_hash.rb +113 -0
  49. data/lib/mongo/util/xml_to_ruby.rb +105 -0
  50. data/mongo-ruby-driver.gemspec +103 -0
  51. data/test/mongo-qa/_common.rb +8 -0
  52. data/test/mongo-qa/admin +26 -0
  53. data/test/mongo-qa/capped +22 -0
  54. data/test/mongo-qa/count1 +18 -0
  55. data/test/mongo-qa/dbs +22 -0
  56. data/test/mongo-qa/find +10 -0
  57. data/test/mongo-qa/find1 +15 -0
  58. data/test/mongo-qa/gridfs_in +16 -0
  59. data/test/mongo-qa/gridfs_out +17 -0
  60. data/test/mongo-qa/indices +49 -0
  61. data/test/mongo-qa/remove +25 -0
  62. data/test/mongo-qa/stress1 +35 -0
  63. data/test/mongo-qa/test1 +11 -0
  64. data/test/mongo-qa/update +18 -0
  65. data/test/test_admin.rb +69 -0
  66. data/test/test_bson.rb +268 -0
  67. data/test/test_byte_buffer.rb +69 -0
  68. data/test/test_chunk.rb +84 -0
  69. data/test/test_collection.rb +249 -0
  70. data/test/test_connection.rb +101 -0
  71. data/test/test_cursor.rb +331 -0
  72. data/test/test_db.rb +185 -0
  73. data/test/test_db_api.rb +798 -0
  74. data/test/test_db_connection.rb +18 -0
  75. data/test/test_grid_store.rb +284 -0
  76. data/test/test_message.rb +35 -0
  77. data/test/test_objectid.rb +105 -0
  78. data/test/test_ordered_hash.rb +138 -0
  79. data/test/test_round_trip.rb +120 -0
  80. data/test/test_threading.rb +37 -0
  81. metadata +135 -0
@@ -0,0 +1,331 @@
1
+ $LOAD_PATH[0,0] = File.join(File.dirname(__FILE__), '..', 'lib')
2
+ require 'mongo'
3
+ require 'test/unit'
4
+
5
+ # NOTE: assumes Mongo is running
6
+ class CursorTest < Test::Unit::TestCase
7
+
8
+ include Mongo
9
+
10
+ @@db = Connection.new(ENV['MONGO_RUBY_DRIVER_HOST'] || 'localhost',
11
+ ENV['MONGO_RUBY_DRIVER_PORT'] || Connection::DEFAULT_PORT).db('ruby-mongo-test')
12
+ @@coll = @@db.collection('test')
13
+
14
+ def setup
15
+ @@coll.clear
16
+ @@coll.insert('a' => 1) # collection not created until it's used
17
+ @@coll_full_name = 'ruby-mongo-test.test'
18
+ end
19
+
20
+ def teardown
21
+ @@coll.clear
22
+ @@db.error
23
+ end
24
+
25
+ def test_explain
26
+ cursor = @@coll.find('a' => 1)
27
+ explaination = cursor.explain
28
+ assert_not_nil explaination['cursor']
29
+ assert_kind_of Numeric, explaination['n']
30
+ assert_kind_of Numeric, explaination['millis']
31
+ assert_kind_of Numeric, explaination['nscanned']
32
+ end
33
+
34
+ def test_count
35
+ @@coll.clear
36
+
37
+ assert_equal 0, @@coll.find().count()
38
+
39
+ 10.times do |i|
40
+ @@coll.save("x" => i)
41
+ end
42
+
43
+ assert_equal 10, @@coll.find().count()
44
+ assert_kind_of Integer, @@coll.find().count()
45
+ assert_equal 10, @@coll.find({}, :limit => 5).count()
46
+ assert_equal 10, @@coll.find({}, :skip => 5).count()
47
+
48
+ assert_equal 1, @@coll.find({"x" => 1}).count()
49
+ assert_equal 5, @@coll.find({"x" => {"$lt" => 5}}).count()
50
+
51
+ a = @@coll.find()
52
+ b = a.count()
53
+ a.each do |doc|
54
+ break
55
+ end
56
+ assert_equal b, a.count()
57
+
58
+ assert_equal 0, @@db['acollectionthatdoesn'].count()
59
+ end
60
+
61
+ def test_sort
62
+ @@coll.clear
63
+ 5.times{|x| @@coll.insert({"a" => x}) }
64
+
65
+ assert_kind_of Cursor, @@coll.find().sort({:a => 1})
66
+
67
+ assert_equal 0, @@coll.find().sort({:a => 1}).next_object["a"]
68
+ assert_equal 4, @@coll.find().sort({:a => -1}).next_object["a"]
69
+ assert_equal 0, @@coll.find().sort(["a"]).next_object["a"]
70
+
71
+ assert_kind_of Cursor, @@coll.find().sort({:a => -1, :b => 1})
72
+
73
+ assert_equal 4, @@coll.find().sort({:a => 1}).sort({:a => -1}).next_object["a"]
74
+ assert_equal 0, @@coll.find().sort({:a => -1}).sort({:a => 1}).next_object["a"]
75
+
76
+ cursor = @@coll.find()
77
+ cursor.next_object()
78
+ assert_raise InvalidOperation do
79
+ cursor.sort(["a"])
80
+ end
81
+ end
82
+
83
+ def test_limit
84
+ @@coll.clear
85
+
86
+ 10.times do |i|
87
+ @@coll.save("x" => i)
88
+ end
89
+ assert_equal 10, @@coll.find().count()
90
+
91
+ results = @@coll.find().limit(5).to_a
92
+ assert_equal 5, results.length
93
+ end
94
+
95
+ def test_limit_exceptions
96
+ assert_raise ArgumentError do
97
+ cursor = @@coll.find().limit('not-an-integer')
98
+ end
99
+
100
+ cursor = @@coll.find()
101
+ firstResult = cursor.next_object()
102
+ assert_raise InvalidOperation, "Cannot modify the query once it has been run or closed." do
103
+ cursor.limit(1)
104
+ end
105
+
106
+ cursor = @@coll.find()
107
+ cursor.close
108
+ assert_raise InvalidOperation, "Cannot modify the query once it has been run or closed." do
109
+ cursor.limit(1)
110
+ end
111
+ end
112
+
113
+ def test_skip
114
+ @@coll.clear
115
+
116
+ 10.times do |i|
117
+ @@coll.save("x" => i)
118
+ end
119
+ assert_equal 10, @@coll.find().count()
120
+
121
+ all_results = @@coll.find().to_a
122
+ skip_results = @@coll.find().skip(2).to_a
123
+ assert_equal 10, all_results.length
124
+ assert_equal 8, skip_results.length
125
+
126
+ assert_equal all_results.slice(2...10), skip_results
127
+ end
128
+
129
+ def test_skip_exceptions
130
+ assert_raise ArgumentError do
131
+ cursor = @@coll.find().skip('not-an-integer')
132
+ end
133
+
134
+ cursor = @@coll.find()
135
+ firstResult = cursor.next_object()
136
+ assert_raise InvalidOperation, "Cannot modify the query once it has been run or closed." do
137
+ cursor.skip(1)
138
+ end
139
+
140
+ cursor = @@coll.find()
141
+ cursor.close
142
+ assert_raise InvalidOperation, "Cannot modify the query once it has been run or closed." do
143
+ cursor.skip(1)
144
+ end
145
+ end
146
+
147
+ def test_limit_skip_chaining
148
+ @@coll.clear
149
+ 10.times do |i|
150
+ @@coll.save("x" => i)
151
+ end
152
+
153
+ all_results = @@coll.find().to_a
154
+ limited_skip_results = @@coll.find().limit(5).skip(3).to_a
155
+
156
+ assert_equal all_results.slice(3...8), limited_skip_results
157
+ end
158
+
159
+ def test_close_no_query_sent
160
+ begin
161
+ cursor = @@coll.find('a' => 1)
162
+ cursor.close
163
+ assert cursor.closed?
164
+ rescue => ex
165
+ fail ex.to_s
166
+ end
167
+ end
168
+
169
+ def test_refill_via_get_more
170
+ begin
171
+ assert_equal 1, @@coll.count
172
+ 1000.times { |i|
173
+ assert_equal 1 + i, @@coll.count
174
+ @@coll.insert('a' => i)
175
+ }
176
+
177
+ assert_equal 1001, @@coll.count
178
+ count = 0
179
+ @@coll.find.each { |obj|
180
+ count += obj['a']
181
+ }
182
+ assert_equal 1001, @@coll.count
183
+
184
+ # do the same thing again for debugging
185
+ assert_equal 1001, @@coll.count
186
+ count2 = 0
187
+ @@coll.find.each { |obj|
188
+ count2 += obj['a']
189
+ }
190
+ assert_equal 1001, @@coll.count
191
+
192
+ assert_equal count, count2
193
+ assert_equal 499501, count
194
+ rescue Test::Unit::AssertionFailedError => ex
195
+ p @@db.collection_names
196
+ Process.exit 1
197
+ end
198
+ end
199
+
200
+ def test_refill_via_get_more_alt_coll
201
+ begin
202
+ coll = @@db.collection('test-alt-coll')
203
+ coll.clear
204
+ coll.insert('a' => 1) # collection not created until it's used
205
+ assert_equal 1, coll.count
206
+
207
+ 1000.times { |i|
208
+ assert_equal 1 + i, coll.count
209
+ coll.insert('a' => i)
210
+ }
211
+
212
+ assert_equal 1001, coll.count
213
+ count = 0
214
+ coll.find.each { |obj|
215
+ count += obj['a']
216
+ }
217
+ assert_equal 1001, coll.count
218
+
219
+ # do the same thing again for debugging
220
+ assert_equal 1001, coll.count
221
+ count2 = 0
222
+ coll.find.each { |obj|
223
+ count2 += obj['a']
224
+ }
225
+ assert_equal 1001, coll.count
226
+
227
+ assert_equal count, count2
228
+ assert_equal 499501, count
229
+ rescue Test::Unit::AssertionFailedError => ex
230
+ p @@db.collection_names
231
+ Process.exit 1
232
+ end
233
+ end
234
+
235
+ def test_close_after_query_sent
236
+ begin
237
+ cursor = @@coll.find('a' => 1)
238
+ cursor.next_object
239
+ cursor.close
240
+ assert cursor.closed?
241
+ rescue => ex
242
+ fail ex.to_s
243
+ end
244
+ end
245
+
246
+ def test_kill_cursors
247
+ @@coll.drop
248
+
249
+ client_cursors = @@db.db_command("cursorInfo" => 1)["clientCursors_size"]
250
+ by_location = @@db.db_command("cursorInfo" => 1)["byLocation_size"]
251
+
252
+ 10000.times do |i|
253
+ @@coll.insert("i" => i)
254
+ end
255
+
256
+ assert_equal(client_cursors,
257
+ @@db.db_command("cursorInfo" => 1)["clientCursors_size"])
258
+ assert_equal(by_location,
259
+ @@db.db_command("cursorInfo" => 1)["byLocation_size"])
260
+
261
+ 10.times do |i|
262
+ @@coll.find_one()
263
+ end
264
+
265
+ assert_equal(client_cursors,
266
+ @@db.db_command("cursorInfo" => 1)["clientCursors_size"])
267
+ assert_equal(by_location,
268
+ @@db.db_command("cursorInfo" => 1)["byLocation_size"])
269
+
270
+ 10.times do |i|
271
+ a = @@coll.find()
272
+ a.next_object()
273
+ a.close()
274
+ end
275
+
276
+ assert_equal(client_cursors,
277
+ @@db.db_command("cursorInfo" => 1)["clientCursors_size"])
278
+ assert_equal(by_location,
279
+ @@db.db_command("cursorInfo" => 1)["byLocation_size"])
280
+
281
+ a = @@coll.find()
282
+ a.next_object()
283
+
284
+ assert_not_equal(client_cursors,
285
+ @@db.db_command("cursorInfo" => 1)["clientCursors_size"])
286
+ assert_not_equal(by_location,
287
+ @@db.db_command("cursorInfo" => 1)["byLocation_size"])
288
+
289
+ a.close()
290
+
291
+ assert_equal(client_cursors,
292
+ @@db.db_command("cursorInfo" => 1)["clientCursors_size"])
293
+ assert_equal(by_location,
294
+ @@db.db_command("cursorInfo" => 1)["byLocation_size"])
295
+
296
+ a = @@coll.find({}, :limit => 10).next_object()
297
+
298
+ assert_equal(client_cursors,
299
+ @@db.db_command("cursorInfo" => 1)["clientCursors_size"])
300
+ assert_equal(by_location,
301
+ @@db.db_command("cursorInfo" => 1)["byLocation_size"])
302
+
303
+ @@coll.find() do |cursor|
304
+ cursor.next_object()
305
+ end
306
+
307
+ assert_equal(client_cursors,
308
+ @@db.db_command("cursorInfo" => 1)["clientCursors_size"])
309
+ assert_equal(by_location,
310
+ @@db.db_command("cursorInfo" => 1)["byLocation_size"])
311
+
312
+ @@coll.find() { |cursor|
313
+ cursor.next_object()
314
+ }
315
+
316
+ assert_equal(client_cursors,
317
+ @@db.db_command("cursorInfo" => 1)["clientCursors_size"])
318
+ assert_equal(by_location,
319
+ @@db.db_command("cursorInfo" => 1)["byLocation_size"])
320
+ end
321
+
322
+ def test_count_with_fields
323
+ @@coll.clear
324
+ @@coll.save("x" => 1)
325
+
326
+ @@coll.find({}, :fields => ["a"]).each do |doc|
327
+ fail "shouldn't have any results here"
328
+ end
329
+ assert_equal(0, @@coll.find({}, :fields => ["a"]).count())
330
+ end
331
+ end
@@ -0,0 +1,185 @@
1
+ $LOAD_PATH[0,0] = File.join(File.dirname(__FILE__), '..', 'lib')
2
+ require 'digest/md5'
3
+ require 'mongo'
4
+ require 'test/unit'
5
+
6
+ class TestPKFactory
7
+ def create_pk(row)
8
+ row['_id'] ||= Mongo::ObjectID.new
9
+ row
10
+ end
11
+ end
12
+
13
+ # NOTE: assumes Mongo is running
14
+ class DBTest < Test::Unit::TestCase
15
+
16
+ include Mongo
17
+
18
+ @@host = ENV['MONGO_RUBY_DRIVER_HOST'] || 'localhost'
19
+ @@port = ENV['MONGO_RUBY_DRIVER_PORT'] || Connection::DEFAULT_PORT
20
+ @@db = Connection.new(@@host, @@port).db('ruby-mongo-test')
21
+ @@users = @@db.collection('system.users')
22
+
23
+ def setup
24
+ @spongebob = 'spongebob'
25
+ @spongebob_password = 'squarepants'
26
+ @@users.clear
27
+ @@users.insert(:user => @spongebob, :pwd => @@db.send(:hash_password, @spongebob, @spongebob_password))
28
+ end
29
+
30
+ def teardown
31
+ @@users.clear if @@users
32
+ @@db.error
33
+ end
34
+
35
+ def test_close
36
+ @@db.close
37
+ assert !@@db.connected?
38
+ begin
39
+ @@db.collection('test').insert('a' => 1)
40
+ fail "expected 'NilClass' exception"
41
+ rescue => ex
42
+ assert_match /NilClass/, ex.to_s
43
+ ensure
44
+ @@db = Connection.new(@@host, @@port).db('ruby-mongo-test')
45
+ @@users = @@db.collection('system.users')
46
+ end
47
+ end
48
+
49
+ def test_full_coll_name
50
+ coll = @@db.collection('test')
51
+ assert_equal 'ruby-mongo-test.test', @@db.full_coll_name(coll.name)
52
+ end
53
+
54
+ def test_collection_names
55
+ @@db.collection("test").insert("foo" => 5)
56
+ @@db.collection("test.mike").insert("bar" => 0)
57
+
58
+ colls = @@db.collection_names()
59
+ assert colls.include?("test")
60
+ assert colls.include?("test.mike")
61
+ colls.each { |name|
62
+ assert !name.include?("$")
63
+ }
64
+ end
65
+
66
+ def test_collections
67
+ @@db.collection("test.durran").insert("foo" => 5)
68
+ @@db.collection("test.les").insert("bar" => 0)
69
+
70
+ colls = @@db.collections()
71
+ assert_not_nil colls.select { |coll| coll.name == "test.durran" }
72
+ assert_not_nil colls.select { |coll| coll.name == "test.les" }
73
+ assert_equal [], colls.select { |coll| coll.name == "does_not_exist" }
74
+
75
+ assert_kind_of Collection, colls[0]
76
+ end
77
+
78
+ def test_pair
79
+ @@db.close
80
+ @@users = nil
81
+ @@db = Connection.new({:left => "this-should-fail", :right => [@@host, @@port]}).db('ruby-mongo-test')
82
+ assert @@db.connected?
83
+ ensure
84
+ @@db = Connection.new(@@host, @@port).db('ruby-mongo-test') unless @@db.connected?
85
+ @@users = @@db.collection('system.users')
86
+ end
87
+
88
+ def test_pk_factory
89
+ db = Connection.new(@@host, @@port).db('ruby-mongo-test', :pk => TestPKFactory.new)
90
+ coll = db.collection('test')
91
+ coll.clear
92
+
93
+ insert_id = coll.insert('name' => 'Fred', 'age' => 42)
94
+ # new id gets added to returned object
95
+ row = coll.find_one({'name' => 'Fred'})
96
+ oid = row['_id']
97
+ assert_not_nil oid
98
+ assert_equal insert_id, oid
99
+
100
+ oid = ObjectID.new
101
+ data = {'_id' => oid, 'name' => 'Barney', 'age' => 41}
102
+ coll.insert(data)
103
+ row = coll.find_one({'name' => data['name']})
104
+ db_oid = row['_id']
105
+ assert_equal oid, db_oid
106
+ assert_equal data, row
107
+
108
+ coll.clear
109
+ end
110
+
111
+ def test_pk_factory_reset
112
+ db = Connection.new(@@host, @@port).db('ruby-mongo-test')
113
+ db.pk_factory = Object.new # first time
114
+ begin
115
+ db.pk_factory = Object.new
116
+ fail "error: expected exception"
117
+ rescue => ex
118
+ assert_match /can not change PK factory/, ex.to_s
119
+ ensure
120
+ db.close
121
+ end
122
+ end
123
+
124
+ def test_authenticate
125
+ assert !@@db.authenticate('nobody', 'nopassword')
126
+ assert !@@db.authenticate(@spongebob, 'squareliederhosen')
127
+ assert @@db.authenticate(@spongebob, @spongebob_password)
128
+ end
129
+
130
+ def test_logout
131
+ @@db.logout # only testing that we don't throw exception
132
+ end
133
+
134
+ def test_auto_connect
135
+ @@db.close
136
+ db = Connection.new(@@host, @@port, :auto_reconnect => true).db('ruby-mongo-test')
137
+ assert db.connected?
138
+ assert db.auto_reconnect?
139
+ db.close
140
+ assert !db.connected?
141
+ assert db.auto_reconnect?
142
+ db.collection('test').insert('a' => 1)
143
+ assert db.connected?
144
+ ensure
145
+ @@db = Connection.new(@@host, @@port).db('ruby-mongo-test')
146
+ @@users = @@db.collection('system.users')
147
+ end
148
+
149
+ def test_error
150
+ @@db.reset_error_history
151
+ assert_nil @@db.error
152
+ assert !@@db.error?
153
+ assert_nil @@db.previous_error
154
+
155
+ @@db.send(:db_command, :forceerror => 1)
156
+ assert @@db.error?
157
+ assert_not_nil @@db.error
158
+ assert_not_nil @@db.previous_error
159
+
160
+ @@db.send(:db_command, :forceerror => 1)
161
+ assert @@db.error?
162
+ assert @@db.error
163
+ prev_error = @@db.previous_error
164
+ assert_equal 1, prev_error['nPrev']
165
+ assert_equal prev_error["err"], @@db.error
166
+
167
+ @@db.collection('test').find_one
168
+ assert_nil @@db.error
169
+ assert !@@db.error?
170
+ assert @@db.previous_error
171
+ assert_equal 2, @@db.previous_error['nPrev']
172
+
173
+ @@db.reset_error_history
174
+ assert_nil @@db.error
175
+ assert !@@db.error?
176
+ assert_nil @@db.previous_error
177
+ end
178
+
179
+ def test_text_port_number
180
+ db = DB.new('ruby-mongo-test', [[@@host, @@port.to_s]])
181
+ # If there is no error, all is well
182
+ db.collection('users').clear
183
+ end
184
+
185
+ end