mongodb-mongo 0.8 → 0.9
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/README.rdoc +7 -0
- data/lib/mongo/collection.rb +8 -11
- data/lib/mongo/db.rb +21 -31
- data/lib/mongo/message/insert_message.rb +2 -2
- data/lib/mongo/message/message.rb +3 -3
- data/lib/mongo/util/bson.rb +52 -43
- data/mongo-ruby-driver.gemspec +1 -1
- data/tests/test_db_api.rb +114 -14
- metadata +1 -1
data/README.rdoc
CHANGED
@@ -324,6 +324,13 @@ Adrian Madrid, aemadrid@gmail.com
|
|
324
324
|
Aman Gupta, aman@tmm1.net
|
325
325
|
* Collection#save
|
326
326
|
|
327
|
+
Jon Crosby, jon@joncrosby.me
|
328
|
+
* Some code clean-up
|
329
|
+
|
330
|
+
John Nunemaker, http://railstips.org
|
331
|
+
* Collection#create_index takes symbols as well as strings
|
332
|
+
* Fix for Collection#save
|
333
|
+
|
327
334
|
= License
|
328
335
|
|
329
336
|
Copyright 2008-2009 10gen Inc.
|
data/lib/mongo/collection.rb
CHANGED
@@ -76,7 +76,7 @@ module XGen
|
|
76
76
|
# Save an updated +object+ to the collection, or insert it if it doesn't exist already.
|
77
77
|
def save(object)
|
78
78
|
if id = object[:_id] || object['_id']
|
79
|
-
|
79
|
+
repsert({:_id => id}, object)
|
80
80
|
else
|
81
81
|
insert(object)
|
82
82
|
end
|
@@ -171,10 +171,11 @@ function () {
|
|
171
171
|
key[keys[i]] = obj[keys[i]];
|
172
172
|
}
|
173
173
|
|
174
|
-
var aggObj = map
|
174
|
+
var aggObj = map.get(key);
|
175
175
|
if (aggObj == null) {
|
176
176
|
var newObj = Object.extend({}, key);
|
177
|
-
aggObj =
|
177
|
+
aggObj = Object.extend(newObj, initial);
|
178
|
+
map.put(key, aggObj);
|
178
179
|
}
|
179
180
|
reduce_function(obj, aggObj);
|
180
181
|
}
|
@@ -190,14 +191,10 @@ EOS
|
|
190
191
|
}))["result"]
|
191
192
|
end
|
192
193
|
|
193
|
-
#
|
194
|
-
#
|
195
|
-
#
|
196
|
-
#
|
197
|
-
# :keys :: Hash whose keys are the names of the fields that make up
|
198
|
-
# the key and values are integers.
|
199
|
-
#
|
200
|
-
# :ns :: Namespace; same as this collection's name.
|
194
|
+
# Get information on the indexes for the collection +collection_name+.
|
195
|
+
# Returns a hash where the keys are index names (as returned by
|
196
|
+
# Collection#create_index and the values are lists of [key, direction]
|
197
|
+
# pairs specifying the index (as passed to Collection#create_index).
|
201
198
|
def index_information
|
202
199
|
@db.index_information(@name)
|
203
200
|
end
|
data/lib/mongo/db.rb
CHANGED
@@ -390,6 +390,7 @@ module XGen
|
|
390
390
|
oh[:query] = selector || {}
|
391
391
|
doc = db_command(oh)
|
392
392
|
return doc['n'].to_i if ok?(doc)
|
393
|
+
return 0 if doc['errmsg'] == "ns missing"
|
393
394
|
raise "Error with count command: #{doc.inspect}"
|
394
395
|
end
|
395
396
|
|
@@ -425,31 +426,18 @@ module XGen
|
|
425
426
|
raise "Error with drop_index command: #{doc.inspect}" unless ok?(doc)
|
426
427
|
end
|
427
428
|
|
428
|
-
#
|
429
|
-
# Normally called by Collection#index_information.
|
430
|
-
#
|
431
|
-
#
|
432
|
-
#
|
433
|
-
# :keys :: Hash whose keys are the names of the fields that make up
|
434
|
-
# the key and values are integers.
|
435
|
-
#
|
436
|
-
# :ns :: Namespace; same as +collection_name+.
|
429
|
+
# Get information on the indexes for the collection +collection_name+.
|
430
|
+
# Normally called by Collection#index_information. Returns a hash where
|
431
|
+
# the keys are index names (as returned by Collection#create_index and
|
432
|
+
# the values are lists of [key, direction] pairs specifying the index
|
433
|
+
# (as passed to Collection#create_index).
|
437
434
|
def index_information(collection_name)
|
438
435
|
sel = {:ns => full_coll_name(collection_name)}
|
439
|
-
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
h[:keys] = row['key']
|
444
|
-
raise "Keys for index on return from db was nil. Coll = #{full_coll_name(collection_name)}" unless h[:keys]
|
445
|
-
|
446
|
-
h[:ns] = row['ns']
|
447
|
-
raise "Namespace for index on return from db was nil. Coll = #{full_coll_name(collection_name)}" unless h[:ns]
|
448
|
-
h[:ns].sub!(/.*\./, '')
|
449
|
-
raise "Error: ns != collection" unless h[:ns] == collection_name
|
450
|
-
|
451
|
-
h
|
436
|
+
info = {}
|
437
|
+
query(Collection.new(self, SYSTEM_INDEX_COLLECTION), Query.new(sel)).each { |index|
|
438
|
+
info[index['name']] = index['key'].to_a
|
452
439
|
}
|
440
|
+
info
|
453
441
|
end
|
454
442
|
|
455
443
|
# Create a new index on +collection_name+. +field_or_spec+
|
@@ -460,10 +448,10 @@ module XGen
|
|
460
448
|
# enforce a uniqueness constraint.
|
461
449
|
def create_index(collection_name, field_or_spec, unique=false)
|
462
450
|
field_h = OrderedHash.new
|
463
|
-
if field_or_spec.is_a?
|
464
|
-
field_h[field_or_spec] = 1
|
451
|
+
if field_or_spec.is_a?(String) || field_or_spec.is_a?(Symbol)
|
452
|
+
field_h[field_or_spec.to_s] = 1
|
465
453
|
else
|
466
|
-
field_or_spec.each { |f| field_h[f[0]] = f[1] }
|
454
|
+
field_or_spec.each { |f| field_h[f[0].to_s] = f[1] }
|
467
455
|
end
|
468
456
|
name = gen_index_name(field_h)
|
469
457
|
sel = {
|
@@ -473,7 +461,7 @@ module XGen
|
|
473
461
|
:unique => unique
|
474
462
|
}
|
475
463
|
@semaphore.synchronize {
|
476
|
-
send_to_db(InsertMessage.new(@name, SYSTEM_INDEX_COLLECTION, sel))
|
464
|
+
send_to_db(InsertMessage.new(@name, SYSTEM_INDEX_COLLECTION, false, sel))
|
477
465
|
}
|
478
466
|
name
|
479
467
|
end
|
@@ -483,11 +471,13 @@ module XGen
|
|
483
471
|
# possibly modified by @pk_factory.
|
484
472
|
def insert_into_db(collection_name, objects)
|
485
473
|
@semaphore.synchronize {
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
|
474
|
+
if @pk_factory
|
475
|
+
objects.collect! { |o|
|
476
|
+
@pk_factory.create_pk(o)
|
477
|
+
}
|
478
|
+
end
|
479
|
+
send_to_db(InsertMessage.new(@name, collection_name, true, *objects))
|
480
|
+
objects
|
491
481
|
}
|
492
482
|
end
|
493
483
|
|
@@ -23,11 +23,11 @@ module XGen
|
|
23
23
|
|
24
24
|
class InsertMessage < Message
|
25
25
|
|
26
|
-
def initialize(db_name, collection_name, *objs)
|
26
|
+
def initialize(db_name, collection_name, check_keys=true, *objs)
|
27
27
|
super(OP_INSERT)
|
28
28
|
write_int(0)
|
29
29
|
write_string("#{db_name}.#{collection_name}")
|
30
|
-
objs.each { |o| write_doc(o) }
|
30
|
+
objs.each { |o| write_doc(o, check_keys) }
|
31
31
|
end
|
32
32
|
end
|
33
33
|
end
|
@@ -36,7 +36,7 @@ module XGen
|
|
36
36
|
@request_id = (@@class_req_id += 1)
|
37
37
|
@response_id = 0
|
38
38
|
@buf = ByteBuffer.new
|
39
|
-
|
39
|
+
|
40
40
|
@buf.put_int(16) # holder for length
|
41
41
|
@buf.put_int(@request_id)
|
42
42
|
@buf.put_int(0) # response_to
|
@@ -58,8 +58,8 @@ module XGen
|
|
58
58
|
update_message_length
|
59
59
|
end
|
60
60
|
|
61
|
-
def write_doc(hash)
|
62
|
-
@buf.put_array(BSON.new.serialize(hash).to_a)
|
61
|
+
def write_doc(hash, check_keys=false)
|
62
|
+
@buf.put_array(BSON.new.serialize(hash, check_keys).to_a)
|
63
63
|
update_message_length
|
64
64
|
end
|
65
65
|
|
data/lib/mongo/util/bson.rb
CHANGED
@@ -73,11 +73,11 @@ class BSON
|
|
73
73
|
|
74
74
|
begin
|
75
75
|
require 'mongo_ext/cbson'
|
76
|
-
def serialize(obj)
|
77
|
-
@buf = ByteBuffer.new(CBson.serialize(obj))
|
76
|
+
def serialize(obj, check_keys=false)
|
77
|
+
@buf = ByteBuffer.new(CBson.serialize(obj, check_keys))
|
78
78
|
end
|
79
79
|
rescue LoadError
|
80
|
-
def serialize(obj)
|
80
|
+
def serialize(obj, check_keys=false)
|
81
81
|
raise "Document is null" unless obj
|
82
82
|
|
83
83
|
@buf.rewind
|
@@ -86,12 +86,12 @@ class BSON
|
|
86
86
|
|
87
87
|
# Write key/value pairs. Always write _id first if it exists.
|
88
88
|
if obj.has_key? '_id'
|
89
|
-
serialize_key_value('_id', obj['_id'])
|
89
|
+
serialize_key_value('_id', obj['_id'], check_keys)
|
90
90
|
elsif obj.has_key? :_id
|
91
|
-
serialize_key_value('_id', obj[:_id])
|
91
|
+
serialize_key_value('_id', obj[:_id], check_keys)
|
92
92
|
end
|
93
93
|
|
94
|
-
obj.each {|k, v| serialize_key_value(k, v) unless k == '_id' || k == :_id }
|
94
|
+
obj.each {|k, v| serialize_key_value(k, v, check_keys) unless k == '_id' || k == :_id }
|
95
95
|
|
96
96
|
serialize_eoo_element(@buf)
|
97
97
|
@buf.put_int(@buf.size, 0)
|
@@ -99,38 +99,47 @@ class BSON
|
|
99
99
|
end
|
100
100
|
end
|
101
101
|
|
102
|
-
def serialize_key_value(k, v)
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
serialize_object_element(@buf, k, v)
|
111
|
-
when OID
|
112
|
-
serialize_oid_element(@buf, k, v)
|
113
|
-
when ARRAY
|
114
|
-
serialize_array_element(@buf, k, v)
|
115
|
-
when REGEX
|
116
|
-
serialize_regex_element(@buf, k, v)
|
117
|
-
when BOOLEAN
|
118
|
-
serialize_boolean_element(@buf, k, v)
|
119
|
-
when DATE
|
120
|
-
serialize_date_element(@buf, k, v)
|
121
|
-
when NULL
|
122
|
-
serialize_null_element(@buf, k)
|
123
|
-
when REF
|
124
|
-
serialize_dbref_element(@buf, k, v)
|
125
|
-
when BINARY
|
126
|
-
serialize_binary_element(@buf, k, v)
|
127
|
-
when UNDEFINED
|
128
|
-
serialize_undefined_element(@buf, k)
|
129
|
-
when CODE_W_SCOPE
|
130
|
-
serialize_code_w_scope(@buf, k, v)
|
131
|
-
else
|
132
|
-
raise "unhandled type #{type}"
|
102
|
+
def serialize_key_value(k, v, check_keys)
|
103
|
+
k = k.to_s
|
104
|
+
if check_keys
|
105
|
+
if k[0] == ?$
|
106
|
+
raise RuntimeError.new("key #{k} must not start with '$'")
|
107
|
+
end
|
108
|
+
if k.include? ?.
|
109
|
+
raise RuntimeError.new("key #{k} must not contain '.'")
|
133
110
|
end
|
111
|
+
end
|
112
|
+
type = bson_type(v)
|
113
|
+
case type
|
114
|
+
when STRING, SYMBOL
|
115
|
+
serialize_string_element(@buf, k, v, type)
|
116
|
+
when NUMBER, NUMBER_INT
|
117
|
+
serialize_number_element(@buf, k, v, type)
|
118
|
+
when OBJECT
|
119
|
+
serialize_object_element(@buf, k, v, check_keys)
|
120
|
+
when OID
|
121
|
+
serialize_oid_element(@buf, k, v)
|
122
|
+
when ARRAY
|
123
|
+
serialize_array_element(@buf, k, v, check_keys)
|
124
|
+
when REGEX
|
125
|
+
serialize_regex_element(@buf, k, v)
|
126
|
+
when BOOLEAN
|
127
|
+
serialize_boolean_element(@buf, k, v)
|
128
|
+
when DATE
|
129
|
+
serialize_date_element(@buf, k, v)
|
130
|
+
when NULL
|
131
|
+
serialize_null_element(@buf, k)
|
132
|
+
when REF
|
133
|
+
serialize_dbref_element(@buf, k, v)
|
134
|
+
when BINARY
|
135
|
+
serialize_binary_element(@buf, k, v)
|
136
|
+
when UNDEFINED
|
137
|
+
serialize_undefined_element(@buf, k)
|
138
|
+
when CODE_W_SCOPE
|
139
|
+
serialize_code_w_scope(@buf, k, v)
|
140
|
+
else
|
141
|
+
raise "unhandled type #{type}"
|
142
|
+
end
|
134
143
|
end
|
135
144
|
|
136
145
|
begin
|
@@ -344,7 +353,7 @@ class BSON
|
|
344
353
|
oh = OrderedHash.new
|
345
354
|
oh['$ref'] = val.namespace
|
346
355
|
oh['$id'] = val.object_id
|
347
|
-
serialize_object_element(buf, key, oh)
|
356
|
+
serialize_object_element(buf, key, oh, false)
|
348
357
|
end
|
349
358
|
|
350
359
|
def serialize_binary_element(buf, key, val)
|
@@ -391,24 +400,24 @@ class BSON
|
|
391
400
|
buf.put_double(val)
|
392
401
|
else
|
393
402
|
if val > 2**32 / 2 - 1 or val < -2**32 / 2
|
394
|
-
raise RangeError.new
|
403
|
+
raise RangeError.new("MongoDB can only handle 4-byte ints - try converting to a double before saving")
|
395
404
|
end
|
396
405
|
buf.put_int(val)
|
397
406
|
end
|
398
407
|
end
|
399
408
|
|
400
|
-
def serialize_object_element(buf, key, val, opcode=OBJECT)
|
409
|
+
def serialize_object_element(buf, key, val, check_keys, opcode=OBJECT)
|
401
410
|
buf.put(opcode)
|
402
411
|
self.class.serialize_cstr(buf, key)
|
403
|
-
buf.put_array(BSON.new.serialize(val).to_a)
|
412
|
+
buf.put_array(BSON.new.serialize(val, check_keys).to_a)
|
404
413
|
end
|
405
414
|
|
406
|
-
def serialize_array_element(buf, key, val)
|
415
|
+
def serialize_array_element(buf, key, val, check_keys)
|
407
416
|
# Turn array into hash with integer indices as keys
|
408
417
|
h = OrderedHash.new
|
409
418
|
i = 0
|
410
419
|
val.each { |v| h[i] = v; i += 1 }
|
411
|
-
serialize_object_element(buf, key, h, ARRAY)
|
420
|
+
serialize_object_element(buf, key, h, check_keys, ARRAY)
|
412
421
|
end
|
413
422
|
|
414
423
|
def serialize_regex_element(buf, key, val)
|
data/mongo-ruby-driver.gemspec
CHANGED
@@ -79,7 +79,7 @@ TEST_FILES = ['tests/mongo-qa/_common.rb',
|
|
79
79
|
|
80
80
|
Gem::Specification.new do |s|
|
81
81
|
s.name = 'mongo'
|
82
|
-
s.version = '0.
|
82
|
+
s.version = '0.9'
|
83
83
|
s.platform = Gem::Platform::RUBY
|
84
84
|
s.summary = 'Ruby driver for the 10gen Mongo DB'
|
85
85
|
s.description = 'A Ruby driver for the 10gen Mongo DB. For more information about Mongo, see http://www.mongodb.org.'
|
data/tests/test_db_api.rb
CHANGED
@@ -56,6 +56,11 @@ class DBAPITest < Test::Unit::TestCase
|
|
56
56
|
assert docs.detect { |row| row['b'] == 3 }
|
57
57
|
end
|
58
58
|
|
59
|
+
def test_count_on_nonexisting
|
60
|
+
@@db.drop_collection('foo')
|
61
|
+
assert_equal 0, @@db.collection('foo').count()
|
62
|
+
end
|
63
|
+
|
59
64
|
def test_find_simple
|
60
65
|
@r2 = @@coll.insert('a' => 2)
|
61
66
|
@r3 = @@coll.insert('b' => 3)
|
@@ -282,29 +287,55 @@ class DBAPITest < Test::Unit::TestCase
|
|
282
287
|
end
|
283
288
|
|
284
289
|
def test_index_information
|
290
|
+
assert_equal @@coll.index_information.length, 1
|
291
|
+
|
285
292
|
name = @@db.create_index(@@coll.name, 'a')
|
286
|
-
|
287
|
-
assert_equal
|
288
|
-
assert_equal
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
assert_equal name,
|
293
|
-
|
293
|
+
info = @@db.index_information(@@coll.name)
|
294
|
+
assert_equal name, "a_1"
|
295
|
+
assert_equal @@coll.index_information, info
|
296
|
+
assert_equal 2, info.length
|
297
|
+
|
298
|
+
assert info.has_key?(name)
|
299
|
+
assert_equal info[name], [["a", ASCENDING]]
|
300
|
+
ensure
|
301
|
+
@@db.drop_index(@@coll.name, name)
|
302
|
+
end
|
303
|
+
|
304
|
+
def test_index_create_with_symbol
|
305
|
+
assert_equal @@coll.index_information.length, 1
|
306
|
+
|
307
|
+
name = @@db.create_index(@@coll.name, :a)
|
308
|
+
info = @@db.index_information(@@coll.name)
|
309
|
+
assert_equal name, "a_1"
|
310
|
+
assert_equal @@coll.index_information, info
|
311
|
+
assert_equal 2, info.length
|
312
|
+
|
313
|
+
assert info.has_key?(name)
|
314
|
+
assert_equal info[name], [["a", ASCENDING]]
|
294
315
|
ensure
|
295
316
|
@@db.drop_index(@@coll.name, name)
|
296
317
|
end
|
297
318
|
|
298
319
|
def test_multiple_index_cols
|
299
320
|
name = @@db.create_index(@@coll.name, [['a', DESCENDING], ['b', ASCENDING], ['c', DESCENDING]])
|
300
|
-
|
301
|
-
assert_equal 2,
|
321
|
+
info = @@db.index_information(@@coll.name)
|
322
|
+
assert_equal 2, info.length
|
323
|
+
|
324
|
+
assert_equal name, 'a_-1_b_1_c_-1'
|
325
|
+
assert info.has_key?(name)
|
326
|
+
assert_equal [['a', DESCENDING], ['b', ASCENDING], ['c', DESCENDING]], info[name]
|
327
|
+
ensure
|
328
|
+
@@db.drop_index(@@coll.name, name)
|
329
|
+
end
|
330
|
+
|
331
|
+
def test_multiple_index_cols_with_symbols
|
332
|
+
name = @@db.create_index(@@coll.name, [[:a, DESCENDING], [:b, ASCENDING], [:c, DESCENDING]])
|
333
|
+
info = @@db.index_information(@@coll.name)
|
334
|
+
assert_equal 2, info.length
|
302
335
|
|
303
|
-
info = list[1]
|
304
336
|
assert_equal name, 'a_-1_b_1_c_-1'
|
305
|
-
|
306
|
-
|
307
|
-
assert_equal ['a', 'b', 'c'], keys.sort
|
337
|
+
assert info.has_key?(name)
|
338
|
+
assert_equal [['a', DESCENDING], ['b', ASCENDING], ['c', DESCENDING]], info[name]
|
308
339
|
ensure
|
309
340
|
@@db.drop_index(@@coll.name, name)
|
310
341
|
end
|
@@ -327,8 +358,25 @@ class DBAPITest < Test::Unit::TestCase
|
|
327
358
|
test.insert("hello" => "mike")
|
328
359
|
test.insert("hello" => "world")
|
329
360
|
assert @@db.error?
|
361
|
+
end
|
362
|
+
|
363
|
+
def test_index_on_subfield
|
364
|
+
@@db.drop_collection("blah")
|
365
|
+
test = @@db.collection("blah")
|
366
|
+
|
367
|
+
test.insert("hello" => {"a" => 4, "b" => 5})
|
368
|
+
test.insert("hello" => {"a" => 7, "b" => 2})
|
369
|
+
test.insert("hello" => {"a" => 4, "b" => 10})
|
370
|
+
assert !@@db.error?
|
330
371
|
|
331
372
|
@@db.drop_collection("blah")
|
373
|
+
test = @@db.collection("blah")
|
374
|
+
test.create_index("hello.a", unique=true)
|
375
|
+
|
376
|
+
test.insert("hello" => {"a" => 4, "b" => 5})
|
377
|
+
test.insert("hello" => {"a" => 7, "b" => 2})
|
378
|
+
test.insert("hello" => {"a" => 4, "b" => 10})
|
379
|
+
assert @@db.error?
|
332
380
|
end
|
333
381
|
|
334
382
|
def test_array
|
@@ -585,6 +633,58 @@ class DBAPITest < Test::Unit::TestCase
|
|
585
633
|
assert_equal 2, @@coll.count
|
586
634
|
end
|
587
635
|
|
636
|
+
def test_save_with_object_that_has_id_but_does_not_actually_exist_in_collection
|
637
|
+
@@coll.clear
|
638
|
+
|
639
|
+
a = {'_id' => '1', 'hello' => 'world'}
|
640
|
+
@@coll.save(a)
|
641
|
+
assert_equal(1, @@coll.count)
|
642
|
+
assert_equal("world", @@coll.find_first()["hello"])
|
643
|
+
|
644
|
+
a["hello"] = "mike"
|
645
|
+
@@coll.save(a)
|
646
|
+
assert_equal(1, @@coll.count)
|
647
|
+
assert_equal("mike", @@coll.find_first()["hello"])
|
648
|
+
end
|
649
|
+
|
650
|
+
def test_invalid_key_names
|
651
|
+
@@coll.clear
|
652
|
+
|
653
|
+
@@coll.insert({"hello" => "world"})
|
654
|
+
@@coll.insert({"hello" => {"hello" => "world"}})
|
655
|
+
|
656
|
+
assert_raise RuntimeError do
|
657
|
+
@@coll.insert({"$hello" => "world"})
|
658
|
+
end
|
659
|
+
assert_raise RuntimeError do
|
660
|
+
@@coll.insert({"hello" => {"$hello" => "world"}})
|
661
|
+
end
|
662
|
+
|
663
|
+
@@coll.insert({"he$llo" => "world"})
|
664
|
+
@@coll.insert({"hello" => {"hell$o" => "world"}})
|
665
|
+
|
666
|
+
assert_raise RuntimeError do
|
667
|
+
@@coll.insert({".hello" => "world"})
|
668
|
+
end
|
669
|
+
assert_raise RuntimeError do
|
670
|
+
@@coll.insert({"hello" => {".hello" => "world"}})
|
671
|
+
end
|
672
|
+
assert_raise RuntimeError do
|
673
|
+
@@coll.insert({"hello." => "world"})
|
674
|
+
end
|
675
|
+
assert_raise RuntimeError do
|
676
|
+
@@coll.insert({"hello" => {"hello." => "world"}})
|
677
|
+
end
|
678
|
+
assert_raise RuntimeError do
|
679
|
+
@@coll.insert({"hel.lo" => "world"})
|
680
|
+
end
|
681
|
+
assert_raise RuntimeError do
|
682
|
+
@@coll.insert({"hello" => {"hel.lo" => "world"}})
|
683
|
+
end
|
684
|
+
|
685
|
+
@@coll.modify({"hello" => "world"}, {"$inc" => "hello"})
|
686
|
+
end
|
687
|
+
|
588
688
|
# TODO this test fails with error message "Undefed Before end of object"
|
589
689
|
# That is a database error. The undefined type may go away.
|
590
690
|
|