mongodb-mongo 0.10.1 → 0.11
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.
- data/lib/mongo/collection.rb +47 -0
- data/lib/mongo/cursor.rb +11 -7
- data/lib/mongo/db.rb +30 -19
- data/lib/mongo/util/bson.rb +22 -4
- data/mongo-ruby-driver.gemspec +2 -1
- data/tests/test_bson.rb +16 -2
- data/tests/test_db.rb +12 -0
- data/tests/test_db_api.rb +95 -5
- data/tests/test_threading.rb +37 -0
- metadata +2 -1
data/lib/mongo/collection.rb
CHANGED
@@ -26,6 +26,24 @@ module XGen
|
|
26
26
|
attr_reader :db, :name, :hint
|
27
27
|
|
28
28
|
def initialize(db, name)
|
29
|
+
case name
|
30
|
+
when Symbol, String
|
31
|
+
else
|
32
|
+
raise RuntimeError, "new_name must be a string or symbol"
|
33
|
+
end
|
34
|
+
|
35
|
+
name = name.to_s
|
36
|
+
|
37
|
+
if name.empty? or name.include? ".."
|
38
|
+
raise RuntimeError, "collection names cannot be empty"
|
39
|
+
end
|
40
|
+
if name.include? "$" and not name.match(/^\$cmd/)
|
41
|
+
raise RuntimeError, "collection names must not contain '$'"
|
42
|
+
end
|
43
|
+
if name.match(/^\./) or name.match(/\.$/)
|
44
|
+
raise RuntimeError, "collection names must not start or end with '.'"
|
45
|
+
end
|
46
|
+
|
29
47
|
@db, @name = db, name
|
30
48
|
@hint = nil
|
31
49
|
end
|
@@ -192,6 +210,35 @@ EOS
|
|
192
210
|
}))["result"]
|
193
211
|
end
|
194
212
|
|
213
|
+
# Rename this collection.
|
214
|
+
#
|
215
|
+
# If operating in auth mode, client must be authorized as an admin to
|
216
|
+
# perform this operation. Raises an error if +new_name+ is an invalid
|
217
|
+
# collection name.
|
218
|
+
#
|
219
|
+
# :new_name :: new name for this collection
|
220
|
+
def rename(new_name)
|
221
|
+
case new_name
|
222
|
+
when Symbol, String
|
223
|
+
else
|
224
|
+
raise RuntimeError, "new_name must be a string or symbol"
|
225
|
+
end
|
226
|
+
|
227
|
+
new_name = new_name.to_s
|
228
|
+
|
229
|
+
if new_name.empty? or new_name.include? ".."
|
230
|
+
raise RuntimeError, "collection names cannot be empty"
|
231
|
+
end
|
232
|
+
if new_name.include? "$"
|
233
|
+
raise RuntimeError, "collection names must not contain '$'"
|
234
|
+
end
|
235
|
+
if new_name.match(/^\./) or new_name.match(/\.$/)
|
236
|
+
raise RuntimeError, "collection names must not start or end with '.'"
|
237
|
+
end
|
238
|
+
|
239
|
+
@db.rename_collection(@name, new_name)
|
240
|
+
end
|
241
|
+
|
195
242
|
# Get information on the indexes for the collection +collection_name+.
|
196
243
|
# Returns a hash where the keys are index names (as returned by
|
197
244
|
# Collection#create_index and the values are lists of [key, direction]
|
data/lib/mongo/cursor.rb
CHANGED
@@ -31,8 +31,8 @@ module XGen
|
|
31
31
|
|
32
32
|
attr_reader :db, :collection, :query
|
33
33
|
|
34
|
-
def initialize(db, collection, query)
|
35
|
-
@db, @collection, @query = db, collection, query
|
34
|
+
def initialize(db, collection, query, admin=false)
|
35
|
+
@db, @collection, @query, @admin = db, collection, query, admin
|
36
36
|
@num_to_return = @query.number_to_return || 0
|
37
37
|
@cache = []
|
38
38
|
@closed = false
|
@@ -194,8 +194,10 @@ module XGen
|
|
194
194
|
def refill_via_get_more
|
195
195
|
send_query_if_needed
|
196
196
|
return if @cursor_id == 0
|
197
|
-
@db.
|
198
|
-
|
197
|
+
@db._synchronize {
|
198
|
+
@db.send_to_db(GetMoreMessage.new(@admin ? 'admin' : @db.name, @collection.name, @cursor_id))
|
199
|
+
read_all
|
200
|
+
}
|
199
201
|
end
|
200
202
|
|
201
203
|
def object_from_stream
|
@@ -212,9 +214,11 @@ module XGen
|
|
212
214
|
def send_query_if_needed
|
213
215
|
# Run query first time we request an object from the wire
|
214
216
|
unless @query_run
|
215
|
-
@db.
|
216
|
-
|
217
|
-
|
217
|
+
@db._synchronize {
|
218
|
+
@db.send_query_message(QueryMessage.new(@admin ? 'admin' : @db.name, @collection.name, @query))
|
219
|
+
@query_run = true
|
220
|
+
read_all
|
221
|
+
}
|
218
222
|
end
|
219
223
|
end
|
220
224
|
|
data/lib/mongo/db.rb
CHANGED
@@ -173,12 +173,11 @@ module XGen
|
|
173
173
|
raise "error logging out: #{doc.inspect}" unless ok?(doc)
|
174
174
|
end
|
175
175
|
|
176
|
-
# Returns an array of collection names
|
177
|
-
# "database_name.collection_name".
|
176
|
+
# Returns an array of collection names in this database.
|
178
177
|
def collection_names
|
179
178
|
names = collections_info.collect { |doc| doc['name'] || '' }
|
180
|
-
names.
|
181
|
-
names
|
179
|
+
names = names.delete_if {|name| name.index(@name).nil? || name.index('$')}
|
180
|
+
names.map {|name| name.sub(@name + '.', '')}
|
182
181
|
end
|
183
182
|
|
184
183
|
# Returns a cursor over query result hashes. Each hash contains a
|
@@ -205,7 +204,7 @@ module XGen
|
|
205
204
|
# :max :: Max number of records in a capped collection. Optional.
|
206
205
|
def create_collection(name, options={})
|
207
206
|
# First check existence
|
208
|
-
if collection_names.include?(
|
207
|
+
if collection_names.include?(name)
|
209
208
|
if strict?
|
210
209
|
raise "Collection #{name} already exists. Currently in strict mode."
|
211
210
|
else
|
@@ -230,14 +229,14 @@ module XGen
|
|
230
229
|
# new collection. If +strict+ is true, will raise an error if
|
231
230
|
# collection +name+ does not already exists.
|
232
231
|
def collection(name)
|
233
|
-
return Collection.new(self, name) if !strict? || collection_names.include?(
|
232
|
+
return Collection.new(self, name) if !strict? || collection_names.include?(name)
|
234
233
|
raise "Collection #{name} doesn't exist. Currently in strict mode."
|
235
234
|
end
|
236
235
|
|
237
236
|
# Drop collection +name+. Returns +true+ on success or if the
|
238
237
|
# collection does not exist, +false+ otherwise.
|
239
238
|
def drop_collection(name)
|
240
|
-
return true unless collection_names.include?(
|
239
|
+
return true unless collection_names.include?(name)
|
241
240
|
|
242
241
|
ok?(db_command(:drop => name))
|
243
242
|
end
|
@@ -340,21 +339,19 @@ module XGen
|
|
340
339
|
# Note that the query gets sent lazily; the cursor calls
|
341
340
|
# #send_query_message when needed. If the caller never requests an
|
342
341
|
# object from the cursor, the query never gets sent.
|
343
|
-
def query(collection, query)
|
344
|
-
Cursor.new(self, collection, query)
|
342
|
+
def query(collection, query, admin=false)
|
343
|
+
Cursor.new(self, collection, query, admin)
|
345
344
|
end
|
346
345
|
|
347
346
|
# Used by a Cursor to lazily send the query to the database.
|
348
347
|
def send_query_message(query_message)
|
349
|
-
|
350
|
-
send_to_db(query_message)
|
351
|
-
}
|
348
|
+
send_to_db(query_message)
|
352
349
|
end
|
353
350
|
|
354
351
|
# Remove the records that match +selector+ from +collection_name+.
|
355
352
|
# Normally called by Collection#remove or Collection#clear.
|
356
353
|
def remove_from_db(collection_name, selector)
|
357
|
-
|
354
|
+
_synchronize {
|
358
355
|
send_to_db(RemoveMessage.new(@name, collection_name, selector))
|
359
356
|
}
|
360
357
|
end
|
@@ -362,7 +359,7 @@ module XGen
|
|
362
359
|
# Update records in +collection_name+ that match +selector+ by
|
363
360
|
# applying +obj+ as an update. Normally called by Collection#replace.
|
364
361
|
def replace_in_db(collection_name, selector, obj)
|
365
|
-
|
362
|
+
_synchronize {
|
366
363
|
send_to_db(UpdateMessage.new(@name, collection_name, selector, obj, false))
|
367
364
|
}
|
368
365
|
end
|
@@ -374,7 +371,7 @@ module XGen
|
|
374
371
|
# applying +obj+ as an update. If no match, inserts (???). Normally
|
375
372
|
# called by Collection#repsert.
|
376
373
|
def repsert_in_db(collection_name, selector, obj)
|
377
|
-
|
374
|
+
_synchronize {
|
378
375
|
obj = @pk_factory.create_pk(obj) if @pk_factory
|
379
376
|
send_to_db(UpdateMessage.new(@name, collection_name, selector, obj, true))
|
380
377
|
obj
|
@@ -416,6 +413,16 @@ module XGen
|
|
416
413
|
raise "Error with eval command: #{doc.inspect}"
|
417
414
|
end
|
418
415
|
|
416
|
+
# Rename collection +from+ to +to+. Meant to be called by
|
417
|
+
# Collection#rename.
|
418
|
+
def rename_collection(from, to)
|
419
|
+
oh = OrderedHash.new
|
420
|
+
oh[:renameCollection] = "#{@name}.#{from}"
|
421
|
+
oh[:to] = "#{@name}.#{to}"
|
422
|
+
doc = db_command(oh, true)
|
423
|
+
raise "Error renaming collection: #{doc.inspect}" unless ok?(doc)
|
424
|
+
end
|
425
|
+
|
419
426
|
# Drop index +name+ from +collection_name+. Normally called from
|
420
427
|
# Collection#drop_index or Collection#drop_indexes.
|
421
428
|
def drop_index(collection_name, name)
|
@@ -460,7 +467,7 @@ module XGen
|
|
460
467
|
:key => field_h,
|
461
468
|
:unique => unique
|
462
469
|
}
|
463
|
-
|
470
|
+
_synchronize {
|
464
471
|
send_to_db(InsertMessage.new(@name, SYSTEM_INDEX_COLLECTION, false, sel))
|
465
472
|
}
|
466
473
|
name
|
@@ -470,7 +477,7 @@ module XGen
|
|
470
477
|
# Collection#insert. Returns a new array containing +objects+,
|
471
478
|
# possibly modified by @pk_factory.
|
472
479
|
def insert_into_db(collection_name, objects)
|
473
|
-
|
480
|
+
_synchronize {
|
474
481
|
if @pk_factory
|
475
482
|
objects.collect! { |o|
|
476
483
|
@pk_factory.create_pk(o)
|
@@ -511,7 +518,7 @@ module XGen
|
|
511
518
|
# that the "command" key be first.
|
512
519
|
#
|
513
520
|
# Do not call this. Intended for driver use only.
|
514
|
-
def db_command(selector)
|
521
|
+
def db_command(selector, use_admin_db=false)
|
515
522
|
if !selector.kind_of?(OrderedHash)
|
516
523
|
if !selector.kind_of?(Hash) || selector.keys.length > 1
|
517
524
|
raise "db_command must be given an OrderedHash when there is more than one key"
|
@@ -520,7 +527,11 @@ module XGen
|
|
520
527
|
|
521
528
|
q = Query.new(selector)
|
522
529
|
q.number_to_return = 1
|
523
|
-
query(Collection.new(self, SYSTEM_COMMAND_COLLECTION), q).next_object
|
530
|
+
query(Collection.new(self, SYSTEM_COMMAND_COLLECTION), q, use_admin_db).next_object
|
531
|
+
end
|
532
|
+
|
533
|
+
def _synchronize &block
|
534
|
+
@semaphore.synchronize &block
|
524
535
|
end
|
525
536
|
|
526
537
|
private
|
data/lib/mongo/util/bson.rb
CHANGED
@@ -47,6 +47,7 @@ class BSON
|
|
47
47
|
CODE_W_SCOPE = 15
|
48
48
|
NUMBER_INT = 16
|
49
49
|
TIMESTAMP = 17
|
50
|
+
NUMBER_LONG = 18
|
50
51
|
MAXKEY = 127
|
51
52
|
|
52
53
|
if RUBY_VERSION >= '1.9'
|
@@ -180,6 +181,9 @@ class BSON
|
|
180
181
|
when NUMBER_INT
|
181
182
|
key = deserialize_cstr(@buf)
|
182
183
|
doc[key] = deserialize_number_int_data(@buf)
|
184
|
+
when NUMBER_LONG
|
185
|
+
key = deserialize_cstr(@buf)
|
186
|
+
doc[key] = deserialize_number_long_data(@buf)
|
183
187
|
when OID
|
184
188
|
key = deserialize_cstr(@buf)
|
185
189
|
doc[key] = deserialize_oid_data(@buf)
|
@@ -263,6 +267,12 @@ class BSON
|
|
263
267
|
unsigned >= 2**32 / 2 ? unsigned - 2**32 : unsigned
|
264
268
|
end
|
265
269
|
|
270
|
+
def deserialize_number_long_data(buf)
|
271
|
+
# same note as above applies here...
|
272
|
+
unsigned = buf.get_long
|
273
|
+
unsigned >= 2 ** 64 / 2 ? unsigned - 2**64 : unsigned
|
274
|
+
end
|
275
|
+
|
266
276
|
def deserialize_object_data(buf)
|
267
277
|
size = buf.get_int
|
268
278
|
buf.position -= 4
|
@@ -394,15 +404,23 @@ class BSON
|
|
394
404
|
end
|
395
405
|
|
396
406
|
def serialize_number_element(buf, key, val, type)
|
397
|
-
buf.put(type)
|
398
|
-
self.class.serialize_cstr(buf, key)
|
399
407
|
if type == NUMBER
|
408
|
+
buf.put(type)
|
409
|
+
self.class.serialize_cstr(buf, key)
|
400
410
|
buf.put_double(val)
|
401
411
|
else
|
412
|
+
if val > 2**64 / 2 - 1 or val < -2**64 / 2
|
413
|
+
raise RangeError.new("MongoDB can only handle 8-byte ints")
|
414
|
+
end
|
402
415
|
if val > 2**32 / 2 - 1 or val < -2**32 / 2
|
403
|
-
|
416
|
+
buf.put(NUMBER_LONG)
|
417
|
+
self.class.serialize_cstr(buf, key)
|
418
|
+
buf.put_long(val)
|
419
|
+
else
|
420
|
+
buf.put(type)
|
421
|
+
self.class.serialize_cstr(buf, key)
|
422
|
+
buf.put_int(val)
|
404
423
|
end
|
405
|
-
buf.put_int(val)
|
406
424
|
end
|
407
425
|
end
|
408
426
|
|
data/mongo-ruby-driver.gemspec
CHANGED
@@ -75,11 +75,12 @@ TEST_FILES = ['tests/mongo-qa/_common.rb',
|
|
75
75
|
'tests/test_mongo.rb',
|
76
76
|
'tests/test_objectid.rb',
|
77
77
|
'tests/test_ordered_hash.rb',
|
78
|
+
'tests/test_threading.rb',
|
78
79
|
'tests/test_round_trip.rb']
|
79
80
|
|
80
81
|
Gem::Specification.new do |s|
|
81
82
|
s.name = 'mongo'
|
82
|
-
s.version = '0.
|
83
|
+
s.version = '0.11'
|
83
84
|
s.platform = Gem::Platform::RUBY
|
84
85
|
s.summary = 'Ruby driver for the 10gen Mongo DB'
|
85
86
|
s.description = 'A Ruby driver for the 10gen Mongo DB. For more information about Mongo, see http://www.mongodb.org.'
|
data/tests/test_bson.rb
CHANGED
@@ -215,18 +215,32 @@ class BSONTest < Test::Unit::TestCase
|
|
215
215
|
end
|
216
216
|
|
217
217
|
def test_overflow
|
218
|
-
doc = {"x" => 2**
|
218
|
+
doc = {"x" => 2**75}
|
219
219
|
assert_raise RangeError do
|
220
220
|
@b.serialize(doc)
|
221
221
|
end
|
222
222
|
|
223
|
-
doc = {"x" =>
|
223
|
+
doc = {"x" => 9223372036854775}
|
224
|
+
assert_equal doc, @b.deserialize(@b.serialize(doc).to_a)
|
225
|
+
|
226
|
+
doc = {"x" => 9223372036854775807}
|
224
227
|
assert_equal doc, @b.deserialize(@b.serialize(doc).to_a)
|
225
228
|
|
226
229
|
doc["x"] = doc["x"] + 1
|
227
230
|
assert_raise RangeError do
|
228
231
|
@b.serialize(doc)
|
229
232
|
end
|
233
|
+
|
234
|
+
doc = {"x" => -9223372036854775}
|
235
|
+
assert_equal doc, @b.deserialize(@b.serialize(doc).to_a)
|
236
|
+
|
237
|
+
doc = {"x" => -9223372036854775808}
|
238
|
+
assert_equal doc, @b.deserialize(@b.serialize(doc).to_a)
|
239
|
+
|
240
|
+
doc["x"] = doc["x"] - 1
|
241
|
+
assert_raise RangeError do
|
242
|
+
@b.serialize(doc)
|
243
|
+
end
|
230
244
|
end
|
231
245
|
|
232
246
|
def test_do_not_change_original_object
|
data/tests/test_db.rb
CHANGED
@@ -51,6 +51,18 @@ class DBTest < Test::Unit::TestCase
|
|
51
51
|
assert_equal 'ruby-mongo-test.test', @@db.full_coll_name(coll.name)
|
52
52
|
end
|
53
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
|
+
|
54
66
|
def test_pair
|
55
67
|
@@db.close
|
56
68
|
@@users = nil
|
data/tests/test_db_api.rb
CHANGED
@@ -241,25 +241,25 @@ class DBAPITest < Test::Unit::TestCase
|
|
241
241
|
|
242
242
|
def test_drop_collection
|
243
243
|
assert @@db.drop_collection(@@coll.name), "drop of collection #{@@coll.name} failed"
|
244
|
-
assert !@@db.collection_names.include?(@@
|
244
|
+
assert !@@db.collection_names.include?(@@coll.name)
|
245
245
|
end
|
246
246
|
|
247
247
|
def test_other_drop
|
248
|
-
assert @@db.collection_names.include?(@@
|
248
|
+
assert @@db.collection_names.include?(@@coll.name)
|
249
249
|
@@coll.drop
|
250
|
-
assert !@@db.collection_names.include?(@@
|
250
|
+
assert !@@db.collection_names.include?(@@coll.name)
|
251
251
|
end
|
252
252
|
|
253
253
|
def test_collection_names
|
254
254
|
names = @@db.collection_names
|
255
255
|
assert names.length >= 1
|
256
|
-
assert names.include?(@@
|
256
|
+
assert names.include?(@@coll.name)
|
257
257
|
|
258
258
|
coll2 = @@db.collection('test2')
|
259
259
|
coll2.insert('a' => 1) # collection not created until it's used
|
260
260
|
names = @@db.collection_names
|
261
261
|
assert names.length >= 2
|
262
|
-
assert names.include?(@@
|
262
|
+
assert names.include?(@@coll.name)
|
263
263
|
assert names.include?('ruby-mongo-test.test2')
|
264
264
|
ensure
|
265
265
|
@@db.drop_collection('test2')
|
@@ -639,6 +639,28 @@ class DBAPITest < Test::Unit::TestCase
|
|
639
639
|
assert_equal 2, @@coll.count
|
640
640
|
end
|
641
641
|
|
642
|
+
def test_save_long
|
643
|
+
@@coll.clear
|
644
|
+
@@coll.insert("x" => 9223372036854775807)
|
645
|
+
assert_equal 9223372036854775807, @@coll.find_first()["x"]
|
646
|
+
end
|
647
|
+
|
648
|
+
def test_find_by_oid
|
649
|
+
@@coll.clear
|
650
|
+
|
651
|
+
@@coll.save("hello" => "mike")
|
652
|
+
id = @@coll.save("hello" => "world")
|
653
|
+
assert_kind_of ObjectID, id
|
654
|
+
|
655
|
+
assert_equal "world", @@coll.find_first(:_id => id)["hello"]
|
656
|
+
@@coll.find(:_id => id).to_a.each do |doc|
|
657
|
+
assert_equal "world", doc["hello"]
|
658
|
+
end
|
659
|
+
|
660
|
+
id = ObjectID.from_string(id.to_s)
|
661
|
+
assert_equal "world", @@coll.find_first(:_id => id)["hello"]
|
662
|
+
end
|
663
|
+
|
642
664
|
def test_save_with_object_that_has_id_but_does_not_actually_exist_in_collection
|
643
665
|
@@coll.clear
|
644
666
|
|
@@ -691,6 +713,74 @@ class DBAPITest < Test::Unit::TestCase
|
|
691
713
|
@@coll.modify({"hello" => "world"}, {"$inc" => "hello"})
|
692
714
|
end
|
693
715
|
|
716
|
+
def test_collection_names
|
717
|
+
assert_raise RuntimeError do
|
718
|
+
@@db.collection(5)
|
719
|
+
end
|
720
|
+
assert_raise RuntimeError do
|
721
|
+
@@db.collection("")
|
722
|
+
end
|
723
|
+
assert_raise RuntimeError do
|
724
|
+
@@db.collection("te$t")
|
725
|
+
end
|
726
|
+
assert_raise RuntimeError do
|
727
|
+
@@db.collection(".test")
|
728
|
+
end
|
729
|
+
assert_raise RuntimeError do
|
730
|
+
@@db.collection("test.")
|
731
|
+
end
|
732
|
+
assert_raise RuntimeError do
|
733
|
+
@@db.collection("tes..t")
|
734
|
+
end
|
735
|
+
end
|
736
|
+
|
737
|
+
def test_rename_collection
|
738
|
+
@@db.drop_collection("foo")
|
739
|
+
@@db.drop_collection("bar")
|
740
|
+
a = @@db.collection("foo")
|
741
|
+
b = @@db.collection("bar")
|
742
|
+
|
743
|
+
assert_raise RuntimeError do
|
744
|
+
a.rename(5)
|
745
|
+
end
|
746
|
+
assert_raise RuntimeError do
|
747
|
+
a.rename("")
|
748
|
+
end
|
749
|
+
assert_raise RuntimeError do
|
750
|
+
a.rename("te$t")
|
751
|
+
end
|
752
|
+
assert_raise RuntimeError do
|
753
|
+
a.rename(".test")
|
754
|
+
end
|
755
|
+
assert_raise RuntimeError do
|
756
|
+
a.rename("test.")
|
757
|
+
end
|
758
|
+
assert_raise RuntimeError do
|
759
|
+
a.rename("tes..t")
|
760
|
+
end
|
761
|
+
|
762
|
+
assert_equal 0, a.count()
|
763
|
+
assert_equal 0, b.count()
|
764
|
+
|
765
|
+
a.insert("x" => 1)
|
766
|
+
a.insert("x" => 2)
|
767
|
+
|
768
|
+
assert_equal 2, a.count()
|
769
|
+
|
770
|
+
a.rename("bar")
|
771
|
+
|
772
|
+
assert_equal 0, a.count()
|
773
|
+
assert_equal 2, b.count()
|
774
|
+
|
775
|
+
assert_equal 1, b.find().to_a()[0]["x"]
|
776
|
+
assert_equal 2, b.find().to_a()[1]["x"]
|
777
|
+
|
778
|
+
b.rename(:foo)
|
779
|
+
|
780
|
+
assert_equal 2, a.count()
|
781
|
+
assert_equal 0, b.count()
|
782
|
+
end
|
783
|
+
|
694
784
|
# TODO this test fails with error message "Undefed Before end of object"
|
695
785
|
# That is a database error. The undefined type may go away.
|
696
786
|
|
@@ -0,0 +1,37 @@
|
|
1
|
+
$LOAD_PATH[0,0] = File.join(File.dirname(__FILE__), '..', 'lib')
|
2
|
+
require 'mongo'
|
3
|
+
require 'test/unit'
|
4
|
+
|
5
|
+
class TestThreading < Test::Unit::TestCase
|
6
|
+
|
7
|
+
include XGen::Mongo::Driver
|
8
|
+
|
9
|
+
@@host = ENV['MONGO_RUBY_DRIVER_HOST'] || 'localhost'
|
10
|
+
@@port = ENV['MONGO_RUBY_DRIVER_PORT'] || Mongo::DEFAULT_PORT
|
11
|
+
@@db = Mongo.new(@@host, @@port).db('ruby-mongo-test')
|
12
|
+
@@coll = @@db.collection('thread-test-collection')
|
13
|
+
|
14
|
+
def test_threading
|
15
|
+
@@coll.clear
|
16
|
+
|
17
|
+
1000.times do |i|
|
18
|
+
@@coll.insert("x" => i)
|
19
|
+
end
|
20
|
+
|
21
|
+
threads = []
|
22
|
+
|
23
|
+
10.times do |i|
|
24
|
+
threads[i] = Thread.new{
|
25
|
+
sum = 0
|
26
|
+
@@coll.find().each { |document|
|
27
|
+
sum += document["x"]
|
28
|
+
}
|
29
|
+
assert_equal 499500, sum
|
30
|
+
}
|
31
|
+
end
|
32
|
+
|
33
|
+
10.times do |i|
|
34
|
+
threads[i].join
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mongodb-mongo
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: "0.11"
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jim Menard
|
@@ -130,4 +130,5 @@ test_files:
|
|
130
130
|
- tests/test_mongo.rb
|
131
131
|
- tests/test_objectid.rb
|
132
132
|
- tests/test_ordered_hash.rb
|
133
|
+
- tests/test_threading.rb
|
133
134
|
- tests/test_round_trip.rb
|