mongodb-mongo 0.11.1 → 0.12
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/Rakefile +1 -1
- data/bin/standard_benchmark +1 -1
- data/examples/benchmarks.rb +6 -6
- data/lib/mongo.rb +1 -0
- data/lib/mongo/collection.rb +129 -30
- data/lib/mongo/db.rb +25 -7
- data/lib/mongo/errors.rb +27 -0
- data/lib/mongo/util/bson.rb +2 -2
- data/lib/mongo/util/ordered_hash.rb +66 -49
- data/mongo-ruby-driver.gemspec +3 -1
- data/tests/mongo-qa/stress1 +1 -1
- data/tests/test_collection.rb +143 -0
- data/tests/test_db.rb +3 -3
- data/tests/test_db_api.rb +48 -45
- data/tests/test_mongo.rb +11 -0
- data/tests/test_ordered_hash.rb +9 -0
- metadata +3 -1
data/Rakefile
CHANGED
@@ -12,7 +12,7 @@ require 'rbconfig'
|
|
12
12
|
include Config
|
13
13
|
|
14
14
|
gem_command = "gem"
|
15
|
-
gem_command = "gem1.9" if
|
15
|
+
gem_command = "gem1.9" if $0.match(/1\.9$/) # use gem1.9 if we used rake1.9
|
16
16
|
|
17
17
|
# NOTE: some of the tests assume Mongo is running
|
18
18
|
Rake::TestTask.new do |t|
|
data/bin/standard_benchmark
CHANGED
@@ -80,7 +80,7 @@ benchmark('batch insert (medium, no index)', insert_batch, PER_TRIAL/BATCH_SIZE,
|
|
80
80
|
benchmark('batch insert (large, no index)', insert_batch, PER_TRIAL/BATCH_SIZE, db, 'large_bulk', LARGE)
|
81
81
|
|
82
82
|
find_one = Proc.new { |coll, x, i|
|
83
|
-
coll.
|
83
|
+
coll.find_one('x' => x)
|
84
84
|
}
|
85
85
|
benchmark('find_one (small, no index)', find_one, PER_TRIAL, db, 'small_none', PER_TRIAL / 2)
|
86
86
|
benchmark('find_one (medium, no index)', find_one, PER_TRIAL, db, 'medium_none', PER_TRIAL / 2)
|
data/examples/benchmarks.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
require "benchmark"
|
2
|
-
|
2
|
+
|
3
3
|
$LOAD_PATH[0,0] = File.join(File.dirname(__FILE__), '..', 'lib')
|
4
4
|
require 'mongo'
|
5
5
|
|
@@ -20,21 +20,21 @@ arr = (0..OBJS_COUNT).collect {|x| { :number => x, :rndm => (rand(5)+1), :msg =>
|
|
20
20
|
|
21
21
|
puts "Running benchmark"
|
22
22
|
Benchmark.bmbm do |results|
|
23
|
-
results.report("single object inserts: ") {
|
23
|
+
results.report("single object inserts: ") {
|
24
24
|
TEST_COUNT.times {
|
25
25
|
coll.clear
|
26
|
-
arr.each {|x| coll.insert(x)}
|
26
|
+
arr.each {|x| coll.insert(x)}
|
27
27
|
}
|
28
28
|
}
|
29
|
-
results.report("multiple object insert: ") {
|
29
|
+
results.report("multiple object insert: ") {
|
30
30
|
TEST_COUNT.times {
|
31
31
|
coll.clear
|
32
32
|
coll.insert(arr)
|
33
33
|
}
|
34
34
|
}
|
35
|
-
results.report("
|
35
|
+
results.report("find_one: ") {
|
36
36
|
TEST_COUNT.times {
|
37
|
-
coll.
|
37
|
+
coll.find_one(:number => 0)
|
38
38
|
}
|
39
39
|
}
|
40
40
|
end
|
data/lib/mongo.rb
CHANGED
data/lib/mongo/collection.rb
CHANGED
@@ -29,25 +29,36 @@ module XGen
|
|
29
29
|
case name
|
30
30
|
when Symbol, String
|
31
31
|
else
|
32
|
-
raise
|
32
|
+
raise TypeError, "new_name must be a string or symbol"
|
33
33
|
end
|
34
34
|
|
35
35
|
name = name.to_s
|
36
36
|
|
37
37
|
if name.empty? or name.include? ".."
|
38
|
-
raise
|
38
|
+
raise InvalidName, "collection names cannot be empty"
|
39
39
|
end
|
40
40
|
if name.include? "$" and not name.match(/^\$cmd/)
|
41
|
-
raise
|
41
|
+
raise InvalidName, "collection names must not contain '$'"
|
42
42
|
end
|
43
43
|
if name.match(/^\./) or name.match(/\.$/)
|
44
|
-
raise
|
44
|
+
raise InvalidName, "collection names must not start or end with '.'"
|
45
45
|
end
|
46
46
|
|
47
47
|
@db, @name = db, name
|
48
48
|
@hint = nil
|
49
49
|
end
|
50
50
|
|
51
|
+
# Get a sub-collection of this collection by name.
|
52
|
+
#
|
53
|
+
# Raises InvalidName if an invalid collection name is used.
|
54
|
+
#
|
55
|
+
# :name :: the name of the collection to get
|
56
|
+
def [](name)
|
57
|
+
name = "#{self.name}.#{name}"
|
58
|
+
return Collection.new(self, name) if !db.strict? || db.collection_names.include?(name)
|
59
|
+
raise "Collection #{name} doesn't exist. Currently in strict mode."
|
60
|
+
end
|
61
|
+
|
51
62
|
# Set hint fields to use and return +self+. hint may be a single field
|
52
63
|
# name, array of field names, or a hash (preferably an OrderedHash).
|
53
64
|
# May be +nil+.
|
@@ -89,31 +100,82 @@ module XGen
|
|
89
100
|
@db.query(self, Query.new(selector, fields, offset, limit, sort, hint, snapshot))
|
90
101
|
end
|
91
102
|
|
103
|
+
# Get a single object from the database.
|
104
|
+
#
|
105
|
+
# Raises TypeError if the argument is of an improper type. Returns a
|
106
|
+
# single document (hash), or nil if no result is found.
|
107
|
+
#
|
108
|
+
# :spec_or_object_id :: a hash specifying elements which must be
|
109
|
+
# present for a document to be included in the result set OR an
|
110
|
+
# instance of ObjectID to be used as the value for an _id query.
|
111
|
+
# if nil an empty spec, {}, will be used.
|
112
|
+
# :options :: options, as passed to Collection#find
|
113
|
+
def find_one(spec_or_object_id=nil, options={})
|
114
|
+
spec = case spec_or_object_id
|
115
|
+
when nil
|
116
|
+
{}
|
117
|
+
when ObjectID
|
118
|
+
{:_id => spec_or_object_id}
|
119
|
+
when Hash
|
120
|
+
spec_or_object_id
|
121
|
+
else
|
122
|
+
raise TypeError, "spec_or_object_id must be an instance of ObjectID or Hash, or nil"
|
123
|
+
end
|
124
|
+
find(spec, options.merge(:limit => -1)).next_object
|
125
|
+
end
|
126
|
+
|
127
|
+
# DEPRECATED - use find_one instead
|
128
|
+
#
|
92
129
|
# Find the first record that matches +selector+. See #find.
|
93
130
|
def find_first(selector={}, options={})
|
94
|
-
|
95
|
-
|
96
|
-
cursor = find(selector, h)
|
97
|
-
cursor.next_object # don't need to explicitly close b/c of limit
|
131
|
+
warn "Collection#find_first is deprecated and will be removed. Please use Collection#find_one instead."
|
132
|
+
find_one(selector, options)
|
98
133
|
end
|
99
134
|
|
100
|
-
# Save
|
101
|
-
|
102
|
-
|
103
|
-
|
135
|
+
# Save a document in this collection.
|
136
|
+
#
|
137
|
+
# If +to_save+ already has an '_id' then an update (upsert) operation
|
138
|
+
# is performed and any existing document with that _id is overwritten.
|
139
|
+
# Otherwise an insert operation is performed. Returns the _id of the
|
140
|
+
# saved document.
|
141
|
+
#
|
142
|
+
# :to_save :: the document (a hash) to be saved
|
143
|
+
#
|
144
|
+
# Options:
|
145
|
+
# :safe :: if true, check that the save succeeded. OperationFailure
|
146
|
+
# will be raised on an error. Checking for safety requires an extra
|
147
|
+
# round-trip to the database
|
148
|
+
def save(to_save, options={})
|
149
|
+
if id = to_save[:_id] || to_save['_id']
|
150
|
+
update({:_id => id}, to_save, :upsert => true, :safe => options.delete(:safe))
|
104
151
|
id
|
105
152
|
else
|
106
|
-
insert(
|
153
|
+
insert(to_save, :safe => options.delete(:safe))
|
107
154
|
end
|
108
155
|
end
|
109
156
|
|
110
|
-
# Insert
|
111
|
-
#
|
112
|
-
#
|
113
|
-
#
|
114
|
-
|
115
|
-
|
116
|
-
|
157
|
+
# Insert a document(s) into this collection.
|
158
|
+
#
|
159
|
+
# "<<" is aliased to this method. Returns the _id of the inserted
|
160
|
+
# document or a list of _ids of the inserted documents. The object(s)
|
161
|
+
# may have been modified by the database's PK factory, if it has one.
|
162
|
+
#
|
163
|
+
# :doc_or_docs :: a document (as a hash) or Array of documents to be
|
164
|
+
# inserted
|
165
|
+
#
|
166
|
+
# Options:
|
167
|
+
# :safe :: if true, check that the insert succeeded. OperationFailure
|
168
|
+
# will be raised on an error. Checking for safety requires an extra
|
169
|
+
# round-trip to the database
|
170
|
+
def insert(doc_or_docs, options={})
|
171
|
+
doc_or_docs = [doc_or_docs] if !doc_or_docs.is_a?(Array)
|
172
|
+
res = @db.insert_into_db(@name, doc_or_docs)
|
173
|
+
if options.delete(:safe)
|
174
|
+
error = @db.error
|
175
|
+
if error
|
176
|
+
raise OperationFailure, error
|
177
|
+
end
|
178
|
+
end
|
117
179
|
res.size > 1 ? res : res.first
|
118
180
|
end
|
119
181
|
alias_method :<<, :insert
|
@@ -128,23 +190,60 @@ module XGen
|
|
128
190
|
remove({})
|
129
191
|
end
|
130
192
|
|
193
|
+
# DEPRECATED - use update(... :upsert => true) instead
|
194
|
+
#
|
131
195
|
# Update records that match +selector+ by applying +obj+ as an update.
|
132
196
|
# If no match, inserts (???).
|
133
197
|
def repsert(selector, obj)
|
134
|
-
|
198
|
+
warn "Collection#repsert is deprecated and will be removed. Please use Collection#update instead."
|
199
|
+
update(selector, obj, :upsert => true)
|
135
200
|
end
|
136
201
|
|
202
|
+
# DEPRECATED - use update(... :upsert => false) instead
|
203
|
+
#
|
137
204
|
# Update records that match +selector+ by applying +obj+ as an update.
|
138
205
|
def replace(selector, obj)
|
139
|
-
|
206
|
+
warn "Collection#replace is deprecated and will be removed. Please use Collection#update instead."
|
207
|
+
update(selector, obj)
|
140
208
|
end
|
141
209
|
|
210
|
+
# DEPRECATED - use update(... :upsert => false) instead
|
211
|
+
#
|
142
212
|
# Update records that match +selector+ by applying +obj+ as an update.
|
143
213
|
# Both +selector+ and +modifier_obj+ are required.
|
144
214
|
def modify(selector, modifier_obj)
|
145
|
-
|
146
|
-
|
147
|
-
|
215
|
+
warn "Collection#modify is deprecated and will be removed. Please use Collection#update instead."
|
216
|
+
update(selector, modifier_obj)
|
217
|
+
end
|
218
|
+
|
219
|
+
# Update a document(s) in this collection.
|
220
|
+
#
|
221
|
+
# :spec :: a hash specifying elements which must be present for
|
222
|
+
# a document to be updated
|
223
|
+
# :document :: a hash specifying the fields to be changed in the
|
224
|
+
# selected document(s), or (in the case of an upsert) the document to
|
225
|
+
# be inserted
|
226
|
+
#
|
227
|
+
# Options:
|
228
|
+
# :upsert :: if true, perform an upsert operation
|
229
|
+
# :safe :: if true, check that the update succeeded. OperationFailure
|
230
|
+
# will be raised on an error. Checking for safety requires an extra
|
231
|
+
# round-trip to the database
|
232
|
+
def update(spec, document, options={})
|
233
|
+
upsert = options.delete(:upsert)
|
234
|
+
safe = options.delete(:safe)
|
235
|
+
|
236
|
+
if upsert
|
237
|
+
@db.repsert_in_db(@name, spec, document)
|
238
|
+
else
|
239
|
+
@db.replace_in_db(@name, spec, document)
|
240
|
+
end
|
241
|
+
if safe
|
242
|
+
error = @db.error
|
243
|
+
if error
|
244
|
+
raise OperationFailure, error
|
245
|
+
end
|
246
|
+
end
|
148
247
|
end
|
149
248
|
|
150
249
|
# Create a new index. +field_or_spec+
|
@@ -219,7 +318,7 @@ EOS
|
|
219
318
|
# Rename this collection.
|
220
319
|
#
|
221
320
|
# If operating in auth mode, client must be authorized as an admin to
|
222
|
-
# perform this operation. Raises
|
321
|
+
# perform this operation. Raises +InvalidName+ if +new_name+ is an invalid
|
223
322
|
# collection name.
|
224
323
|
#
|
225
324
|
# :new_name :: new name for this collection
|
@@ -227,19 +326,19 @@ EOS
|
|
227
326
|
case new_name
|
228
327
|
when Symbol, String
|
229
328
|
else
|
230
|
-
raise
|
329
|
+
raise TypeError, "new_name must be a string or symbol"
|
231
330
|
end
|
232
331
|
|
233
332
|
new_name = new_name.to_s
|
234
333
|
|
235
334
|
if new_name.empty? or new_name.include? ".."
|
236
|
-
raise
|
335
|
+
raise InvalidName, "collection names cannot be empty"
|
237
336
|
end
|
238
337
|
if new_name.include? "$"
|
239
|
-
raise
|
338
|
+
raise InvalidName, "collection names must not contain '$'"
|
240
339
|
end
|
241
340
|
if new_name.match(/^\./) or new_name.match(/\.$/)
|
242
|
-
raise
|
341
|
+
raise InvalidName, "collection names must not start or end with '.'"
|
243
342
|
end
|
244
343
|
|
245
344
|
@db.rename_collection(@name, new_name)
|
data/lib/mongo/db.rb
CHANGED
@@ -114,7 +114,21 @@ module XGen
|
|
114
114
|
# instance and connect to that one. On socket error or if we recieve a
|
115
115
|
# "not master" error, we again find the master of the pair.
|
116
116
|
def initialize(db_name, nodes, options={})
|
117
|
-
|
117
|
+
case db_name
|
118
|
+
when Symbol, String
|
119
|
+
else
|
120
|
+
raise TypeError, "db_name must be a string or symbol"
|
121
|
+
end
|
122
|
+
|
123
|
+
[" ", ".", "$", "/", "\\"].each do |invalid_char|
|
124
|
+
if db_name.include? invalid_char
|
125
|
+
raise InvalidName, "database names cannot contain the character '#{invalid_char}'"
|
126
|
+
end
|
127
|
+
end
|
128
|
+
if db_name.empty?
|
129
|
+
raise InvalidName, "database name cannot be the empty string"
|
130
|
+
end
|
131
|
+
|
118
132
|
@name, @nodes = db_name, nodes
|
119
133
|
@strict = options[:strict]
|
120
134
|
@pk_factory = options[:pk]
|
@@ -232,6 +246,7 @@ module XGen
|
|
232
246
|
return Collection.new(self, name) if !strict? || collection_names.include?(name)
|
233
247
|
raise "Collection #{name} doesn't exist. Currently in strict mode."
|
234
248
|
end
|
249
|
+
alias_method :[], :collection
|
235
250
|
|
236
251
|
# Drop collection +name+. Returns +true+ on success or if the
|
237
252
|
# collection does not exist, +false+ otherwise.
|
@@ -364,8 +379,11 @@ module XGen
|
|
364
379
|
}
|
365
380
|
end
|
366
381
|
|
367
|
-
#
|
368
|
-
|
382
|
+
# DEPRECATED - use Collection#update instead
|
383
|
+
def modify_in_db(collection_name, selector, obj)
|
384
|
+
warn "DB#modify_in_db is deprecated and will be removed. Please use Collection#update instead."
|
385
|
+
replace_in_db(collection_name, selector, obj)
|
386
|
+
end
|
369
387
|
|
370
388
|
# Update records in +collection_name+ that match +selector+ by
|
371
389
|
# applying +obj+ as an update. If no match, inserts (???). Normally
|
@@ -393,7 +411,7 @@ module XGen
|
|
393
411
|
|
394
412
|
# Dereference a DBRef, getting the document it points to.
|
395
413
|
def dereference(dbref)
|
396
|
-
collection(dbref.namespace).
|
414
|
+
collection(dbref.namespace).find_one("_id" => dbref.object_id)
|
397
415
|
end
|
398
416
|
|
399
417
|
# Evaluate a JavaScript expression on MongoDB.
|
@@ -474,8 +492,8 @@ module XGen
|
|
474
492
|
end
|
475
493
|
|
476
494
|
# Insert +objects+ into +collection_name+. Normally called by
|
477
|
-
# Collection#insert. Returns a new array containing
|
478
|
-
#
|
495
|
+
# Collection#insert. Returns a new array containing the _ids
|
496
|
+
# of the inserted documents.
|
479
497
|
def insert_into_db(collection_name, objects)
|
480
498
|
_synchronize {
|
481
499
|
if @pk_factory
|
@@ -484,7 +502,7 @@ module XGen
|
|
484
502
|
}
|
485
503
|
else
|
486
504
|
objects = objects.collect do |o|
|
487
|
-
o[:_id] || o['_id'] ? o : o.merge(:_id => ObjectID.new)
|
505
|
+
o[:_id] || o['_id'] ? o : o.merge!(:_id => ObjectID.new)
|
488
506
|
end
|
489
507
|
end
|
490
508
|
send_to_db(InsertMessage.new(@name, collection_name, true, *objects))
|
data/lib/mongo/errors.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# Copyright 2009 10gen, Inc.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
# Exceptions raised by the MongoDB driver.
|
16
|
+
|
17
|
+
module XGen
|
18
|
+
module Mongo
|
19
|
+
module Driver
|
20
|
+
# Raised when a database operation fails.
|
21
|
+
class OperationFailure < RuntimeError; end
|
22
|
+
|
23
|
+
# Raised when an invalid name is used.
|
24
|
+
class InvalidName < RuntimeError; end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
data/lib/mongo/util/bson.rb
CHANGED
@@ -104,10 +104,10 @@ class BSON
|
|
104
104
|
k = k.to_s
|
105
105
|
if check_keys
|
106
106
|
if k[0] == ?$
|
107
|
-
raise
|
107
|
+
raise InvalidName.new("key #{k} must not start with '$'")
|
108
108
|
end
|
109
109
|
if k.include? ?.
|
110
|
-
raise
|
110
|
+
raise InvalidName.new("key #{k} must not contain '.'")
|
111
111
|
end
|
112
112
|
end
|
113
113
|
type = bson_type(v)
|
@@ -32,65 +32,82 @@ class OrderedHash < Hash
|
|
32
32
|
|
33
33
|
# We only need the body of this class if the RUBY_VERSION is before 1.9
|
34
34
|
if RUBY_VERSION < '1.9'
|
35
|
+
attr_accessor :ordered_keys
|
36
|
+
|
37
|
+
def self.[] *args
|
38
|
+
oh = OrderedHash.new
|
39
|
+
if Hash === args[0]
|
40
|
+
oh.merge! args[0]
|
41
|
+
elsif (args.size % 2) != 0
|
42
|
+
raise ArgumentError, "odd number of elements for Hash"
|
43
|
+
else
|
44
|
+
0.step(args.size - 1, 2) do |key|
|
45
|
+
value = key + 1
|
46
|
+
oh[args[key]] = args[value]
|
47
|
+
end
|
48
|
+
end
|
49
|
+
oh
|
50
|
+
end
|
35
51
|
|
36
|
-
|
52
|
+
def initialize(*a, &b)
|
53
|
+
super
|
54
|
+
@ordered_keys = []
|
55
|
+
end
|
37
56
|
|
38
|
-
|
39
|
-
|
40
|
-
|
57
|
+
def keys
|
58
|
+
@ordered_keys || []
|
59
|
+
end
|
41
60
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
61
|
+
def []=(key, value)
|
62
|
+
@ordered_keys ||= []
|
63
|
+
@ordered_keys << key unless @ordered_keys.include?(key)
|
64
|
+
super(key, value)
|
65
|
+
end
|
47
66
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
67
|
+
def each
|
68
|
+
@ordered_keys ||= []
|
69
|
+
@ordered_keys.each { |k| yield k, self[k] }
|
70
|
+
end
|
52
71
|
|
53
|
-
|
54
|
-
|
55
|
-
|
72
|
+
def values
|
73
|
+
collect { |k, v| v }
|
74
|
+
end
|
56
75
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
76
|
+
def merge(other)
|
77
|
+
oh = self.dup
|
78
|
+
oh.merge!(other)
|
79
|
+
oh
|
80
|
+
end
|
62
81
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
82
|
+
def merge!(other)
|
83
|
+
@ordered_keys ||= []
|
84
|
+
@ordered_keys += other.keys # unordered if not an OrderedHash
|
85
|
+
@ordered_keys.uniq!
|
86
|
+
super(other)
|
87
|
+
end
|
69
88
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
89
|
+
def inspect
|
90
|
+
str = '{'
|
91
|
+
str << (@ordered_keys || []).collect { |k| "\"#{k}\"=>#{self.[](k).inspect}" }.join(", ")
|
92
|
+
str << '}'
|
93
|
+
end
|
75
94
|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
95
|
+
def delete(key, &block)
|
96
|
+
@ordered_keys.delete(key) if @ordered_keys
|
97
|
+
super
|
98
|
+
end
|
80
99
|
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
100
|
+
def delete_if(&block)
|
101
|
+
self.each { |k,v|
|
102
|
+
if yield k, v
|
103
|
+
delete(k)
|
104
|
+
end
|
105
|
+
}
|
106
|
+
end
|
88
107
|
|
89
|
-
|
90
|
-
|
91
|
-
|
108
|
+
def clear
|
109
|
+
super
|
110
|
+
@ordered_keys = []
|
111
|
+
end
|
92
112
|
end
|
93
|
-
|
94
|
-
end # Ruby before 1.9
|
95
|
-
|
96
113
|
end
|
data/mongo-ruby-driver.gemspec
CHANGED
@@ -24,6 +24,7 @@ PACKAGE_FILES = ['README.rdoc', 'Rakefile', 'mongo-ruby-driver.gemspec',
|
|
24
24
|
'lib/mongo/gridfs/chunk.rb',
|
25
25
|
'lib/mongo/gridfs/grid_store.rb',
|
26
26
|
'lib/mongo/gridfs.rb',
|
27
|
+
'lib/mongo/errors.rb',
|
27
28
|
'lib/mongo/message/get_more_message.rb',
|
28
29
|
'lib/mongo/message/insert_message.rb',
|
29
30
|
'lib/mongo/message/kill_cursors_message.rb',
|
@@ -66,6 +67,7 @@ TEST_FILES = ['tests/mongo-qa/_common.rb',
|
|
66
67
|
'tests/test_bson.rb',
|
67
68
|
'tests/test_byte_buffer.rb',
|
68
69
|
'tests/test_chunk.rb',
|
70
|
+
'tests/test_collection.rb',
|
69
71
|
'tests/test_cursor.rb',
|
70
72
|
'tests/test_db.rb',
|
71
73
|
'tests/test_db_api.rb',
|
@@ -80,7 +82,7 @@ TEST_FILES = ['tests/mongo-qa/_common.rb',
|
|
80
82
|
|
81
83
|
Gem::Specification.new do |s|
|
82
84
|
s.name = 'mongo'
|
83
|
-
s.version = '0.
|
85
|
+
s.version = '0.12'
|
84
86
|
s.platform = Gem::Platform::RUBY
|
85
87
|
s.summary = 'Ruby driver for the 10gen Mongo DB'
|
86
88
|
s.description = 'A Ruby driver for the 10gen Mongo DB. For more information about Mongo, see http://www.mongodb.org.'
|
data/tests/mongo-qa/stress1
CHANGED
@@ -0,0 +1,143 @@
|
|
1
|
+
# --
|
2
|
+
# Copyright (C) 2008-2009 10gen Inc.
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
# ++
|
16
|
+
|
17
|
+
$LOAD_PATH[0,0] = File.join(File.dirname(__FILE__), '..', 'lib')
|
18
|
+
require 'mongo'
|
19
|
+
require 'test/unit'
|
20
|
+
|
21
|
+
# NOTE: assumes Mongo is running
|
22
|
+
class TestCollection < Test::Unit::TestCase
|
23
|
+
include XGen::Mongo
|
24
|
+
include XGen::Mongo::Driver
|
25
|
+
|
26
|
+
@@db = Mongo.new(ENV['MONGO_RUBY_DRIVER_HOST'] || 'localhost',
|
27
|
+
ENV['MONGO_RUBY_DRIVER_PORT'] || Mongo::DEFAULT_PORT).db('ruby-mongo-test')
|
28
|
+
@@test = @@db.collection("test")
|
29
|
+
|
30
|
+
def setup
|
31
|
+
@@test.drop()
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_collection
|
35
|
+
assert_raise InvalidName do
|
36
|
+
@@db["te$t"]
|
37
|
+
end
|
38
|
+
|
39
|
+
assert_kind_of Collection, @@db["test"]
|
40
|
+
assert_equal @@db["test"].name(), @@db.collection("test").name()
|
41
|
+
assert_equal @@db["test"].name(), @@db[:test].name()
|
42
|
+
|
43
|
+
assert_kind_of Collection, @@db["test"]["foo"]
|
44
|
+
assert_equal @@db["test"]["foo"].name(), @@db.collection("test.foo").name()
|
45
|
+
assert_equal @@db["test"]["foo"].name(), @@db["test.foo"].name()
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_safe_insert
|
49
|
+
a = {"hello" => "world"}
|
50
|
+
@@test.insert(a)
|
51
|
+
@@test.insert(a)
|
52
|
+
assert @@db.error.include? "E11000"
|
53
|
+
|
54
|
+
assert_raise OperationFailure do
|
55
|
+
@@test.insert(a, :safe => true)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def test_update
|
60
|
+
id1 = @@test.save("x" => 5)
|
61
|
+
@@test.update({}, {"$inc" => {"x" => 1}})
|
62
|
+
assert_equal 1, @@test.count()
|
63
|
+
assert_equal 6, @@test.find_one(:_id => id1)["x"]
|
64
|
+
|
65
|
+
id2 = @@test.save("x" => 1)
|
66
|
+
@@test.update({"x" => 6}, {"$inc" => {"x" => 1}})
|
67
|
+
assert_equal 7, @@test.find_one(:_id => id1)["x"]
|
68
|
+
assert_equal 1, @@test.find_one(:_id => id2)["x"]
|
69
|
+
end
|
70
|
+
|
71
|
+
def test_upsert
|
72
|
+
@@test.update({"page" => "/"}, {"$inc" => {"count" => 1}}, :upsert => true)
|
73
|
+
@@test.update({"page" => "/"}, {"$inc" => {"count" => 1}}, :upsert => true)
|
74
|
+
|
75
|
+
assert_equal 1, @@test.count()
|
76
|
+
assert_equal 2, @@test.find_one()["count"]
|
77
|
+
end
|
78
|
+
|
79
|
+
def test_safe_update
|
80
|
+
@@test.create_index("x")
|
81
|
+
@@test.insert("x" => 5)
|
82
|
+
|
83
|
+
@@test.update({}, {"$inc" => {"x" => 1}})
|
84
|
+
assert @@db.error?
|
85
|
+
|
86
|
+
assert_raise OperationFailure do
|
87
|
+
@@test.update({}, {"$inc" => {"x" => 1}}, :safe => true)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def test_safe_save
|
92
|
+
@@test.create_index("hello", true)
|
93
|
+
|
94
|
+
@@test.save("hello" => "world")
|
95
|
+
@@test.save("hello" => "world")
|
96
|
+
assert @@db.error.include? "E11000"
|
97
|
+
|
98
|
+
assert_raise OperationFailure do
|
99
|
+
@@test.save({"hello" => "world"}, :safe => true)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def test_find_one
|
104
|
+
id = @@test.save("hello" => "world", "foo" => "bar")
|
105
|
+
|
106
|
+
assert_equal "world", @@test.find_one()["hello"]
|
107
|
+
assert_equal @@test.find_one(id), @@test.find_one()
|
108
|
+
assert_equal @@test.find_one(nil), @@test.find_one()
|
109
|
+
assert_equal @@test.find_one({}), @@test.find_one()
|
110
|
+
assert_equal @@test.find_one("hello" => "world"), @@test.find_one()
|
111
|
+
assert_equal @@test.find_one(OrderedHash["hello", "world"]), @@test.find_one()
|
112
|
+
|
113
|
+
assert @@test.find_one(nil, :fields => ["hello"]).include?("hello")
|
114
|
+
assert !@@test.find_one(nil, :fields => ["foo"]).include?("hello")
|
115
|
+
|
116
|
+
assert_equal nil, @@test.find_one("hello" => "foo")
|
117
|
+
assert_equal nil, @@test.find_one(OrderedHash["hello", "foo"])
|
118
|
+
assert_equal nil, @@test.find_one(ObjectID.new)
|
119
|
+
|
120
|
+
assert_raise TypeError do
|
121
|
+
@@test.find_one(6)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
def test_insert_adds_id
|
126
|
+
doc = {"hello" => "world"}
|
127
|
+
@@test.insert(doc)
|
128
|
+
assert doc.include? :_id
|
129
|
+
|
130
|
+
docs = [{"hello" => "world"}, {"hello" => "world"}]
|
131
|
+
@@test.insert(docs)
|
132
|
+
docs.each do |doc|
|
133
|
+
assert doc.include? :_id
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
def test_save_adds_id
|
138
|
+
doc = {"hello" => "world"}
|
139
|
+
@@test.save(doc)
|
140
|
+
assert doc.include? :_id
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
data/tests/test_db.rb
CHANGED
@@ -80,7 +80,7 @@ class DBTest < Test::Unit::TestCase
|
|
80
80
|
|
81
81
|
insert_id = coll.insert('name' => 'Fred', 'age' => 42)
|
82
82
|
# new id gets added to returned object
|
83
|
-
row = coll.
|
83
|
+
row = coll.find_one({'name' => 'Fred'})
|
84
84
|
oid = row['_id']
|
85
85
|
assert_not_nil oid
|
86
86
|
assert_equal insert_id, oid
|
@@ -88,7 +88,7 @@ class DBTest < Test::Unit::TestCase
|
|
88
88
|
oid = XGen::Mongo::Driver::ObjectID.new
|
89
89
|
data = {'_id' => oid, 'name' => 'Barney', 'age' => 41}
|
90
90
|
coll.insert(data)
|
91
|
-
row = coll.
|
91
|
+
row = coll.find_one({'name' => data['name']})
|
92
92
|
db_oid = row['_id']
|
93
93
|
assert_equal oid, db_oid
|
94
94
|
assert_equal data, row
|
@@ -152,7 +152,7 @@ class DBTest < Test::Unit::TestCase
|
|
152
152
|
assert_equal 1, prev_error['nPrev']
|
153
153
|
assert_equal prev_error["err"], @@db.error
|
154
154
|
|
155
|
-
@@db.collection('test').
|
155
|
+
@@db.collection('test').find_one
|
156
156
|
assert_nil @@db.error
|
157
157
|
assert !@@db.error?
|
158
158
|
assert @@db.previous_error
|
data/tests/test_db_api.rb
CHANGED
@@ -52,11 +52,15 @@ class DBAPITest < Test::Unit::TestCase
|
|
52
52
|
oh['b'] = 'foo'
|
53
53
|
|
54
54
|
oid = @@coll.save(oh)
|
55
|
-
assert_equal 'foo', @@coll.
|
55
|
+
assert_equal 'foo', @@coll.find_one(oid)['b']
|
56
|
+
|
57
|
+
oh = OrderedHash['a' => 1, 'b' => 'foo']
|
58
|
+
oid = @@coll.save(oh)
|
59
|
+
assert_equal 'foo', @@coll.find_one(oid)['b']
|
56
60
|
end
|
57
61
|
|
58
62
|
def test_insert_multiple
|
59
|
-
ids = @@coll.insert({'a' => 2}, {'b' => 3})
|
63
|
+
ids = @@coll.insert([{'a' => 2}, {'b' => 3}])
|
60
64
|
|
61
65
|
ids.each do |i|
|
62
66
|
assert_kind_of ObjectID, i
|
@@ -242,9 +246,9 @@ class DBAPITest < Test::Unit::TestCase
|
|
242
246
|
assert_equal 1, x['a']
|
243
247
|
end
|
244
248
|
|
245
|
-
def
|
249
|
+
def test_find_one_no_records
|
246
250
|
@@coll.clear
|
247
|
-
x = @@coll.
|
251
|
+
x = @@coll.find_one('a' => 1)
|
248
252
|
assert_nil x
|
249
253
|
end
|
250
254
|
|
@@ -469,28 +473,28 @@ class DBAPITest < Test::Unit::TestCase
|
|
469
473
|
|
470
474
|
def test_replace
|
471
475
|
assert_equal @@coll.count, 1
|
472
|
-
assert_equal @@coll.
|
476
|
+
assert_equal @@coll.find_one["a"], 1
|
473
477
|
|
474
478
|
@@coll.replace({"a" => 1}, {"a" => 2})
|
475
479
|
assert_equal @@coll.count, 1
|
476
|
-
assert_equal @@coll.
|
480
|
+
assert_equal @@coll.find_one["a"], 2
|
477
481
|
|
478
482
|
@@coll.replace({"b" => 1}, {"a" => 3})
|
479
483
|
assert_equal @@coll.count, 1
|
480
|
-
assert_equal @@coll.
|
484
|
+
assert_equal @@coll.find_one["a"], 2
|
481
485
|
end
|
482
486
|
|
483
487
|
def test_repsert
|
484
488
|
assert_equal @@coll.count, 1
|
485
|
-
assert_equal @@coll.
|
489
|
+
assert_equal @@coll.find_one["a"], 1
|
486
490
|
|
487
491
|
@@coll.repsert({"a" => 1}, {"a" => 2})
|
488
492
|
assert_equal @@coll.count, 1
|
489
|
-
assert_equal @@coll.
|
493
|
+
assert_equal @@coll.find_one["a"], 2
|
490
494
|
|
491
495
|
@@coll.repsert({"b" => 1}, {"a" => 3})
|
492
496
|
assert_equal @@coll.count, 2
|
493
|
-
assert @@coll.
|
497
|
+
assert @@coll.find_one({"a" => 3})
|
494
498
|
end
|
495
499
|
|
496
500
|
def test_to_a
|
@@ -540,7 +544,7 @@ class DBAPITest < Test::Unit::TestCase
|
|
540
544
|
assert_equal 3, @@db.eval('function (x) {return x;}', 3)
|
541
545
|
|
542
546
|
assert_equal nil, @@db.eval("function (x) {db.test_eval.save({y:x});}", 5)
|
543
|
-
assert_equal 5, @@db.collection('test_eval').
|
547
|
+
assert_equal 5, @@db.collection('test_eval').find_one['y']
|
544
548
|
|
545
549
|
assert_equal 5, @@db.eval("function (x, y) {return x + y;}", 2, 3)
|
546
550
|
assert_equal 5, @@db.eval("function () {return 5;}")
|
@@ -587,7 +591,7 @@ class DBAPITest < Test::Unit::TestCase
|
|
587
591
|
val = Hash.new(0)
|
588
592
|
val["x"] = 5
|
589
593
|
@@coll.insert val
|
590
|
-
id = @@coll.
|
594
|
+
id = @@coll.find_one("x" => 5)["_id"]
|
591
595
|
assert id != 0
|
592
596
|
end
|
593
597
|
|
@@ -610,7 +614,7 @@ class DBAPITest < Test::Unit::TestCase
|
|
610
614
|
|
611
615
|
assert_equal nil, @@db.dereference(DBRef.new("test", ObjectID.new))
|
612
616
|
@@coll.insert({"x" => "hello"})
|
613
|
-
key = @@coll.
|
617
|
+
key = @@coll.find_one()["_id"]
|
614
618
|
assert_equal "hello", @@db.dereference(DBRef.new("test", key))["x"]
|
615
619
|
|
616
620
|
assert_equal nil, @@db.dereference(DBRef.new("test", 4))
|
@@ -632,26 +636,25 @@ class DBAPITest < Test::Unit::TestCase
|
|
632
636
|
assert_kind_of ObjectID, id
|
633
637
|
assert_equal 1, @@coll.count
|
634
638
|
|
635
|
-
assert_equal id, @@coll.save(
|
639
|
+
assert_equal id, @@coll.save(a)
|
636
640
|
assert_equal 1, @@coll.count
|
637
641
|
|
638
|
-
assert_equal "world", @@coll.
|
642
|
+
assert_equal "world", @@coll.find_one()["hello"]
|
639
643
|
|
640
|
-
|
641
|
-
|
642
|
-
@@coll.save(doc)
|
644
|
+
a["hello"] = "mike"
|
645
|
+
@@coll.save(a)
|
643
646
|
assert_equal 1, @@coll.count
|
644
647
|
|
645
|
-
assert_equal "mike", @@coll.
|
648
|
+
assert_equal "mike", @@coll.find_one()["hello"]
|
646
649
|
|
647
|
-
@@coll.save(
|
650
|
+
@@coll.save({"hello" => "world"})
|
648
651
|
assert_equal 2, @@coll.count
|
649
652
|
end
|
650
653
|
|
651
654
|
def test_save_long
|
652
655
|
@@coll.clear
|
653
656
|
@@coll.insert("x" => 9223372036854775807)
|
654
|
-
assert_equal 9223372036854775807, @@coll.
|
657
|
+
assert_equal 9223372036854775807, @@coll.find_one()["x"]
|
655
658
|
end
|
656
659
|
|
657
660
|
def test_find_by_oid
|
@@ -661,13 +664,13 @@ class DBAPITest < Test::Unit::TestCase
|
|
661
664
|
id = @@coll.save("hello" => "world")
|
662
665
|
assert_kind_of ObjectID, id
|
663
666
|
|
664
|
-
assert_equal "world", @@coll.
|
667
|
+
assert_equal "world", @@coll.find_one(:_id => id)["hello"]
|
665
668
|
@@coll.find(:_id => id).to_a.each do |doc|
|
666
669
|
assert_equal "world", doc["hello"]
|
667
670
|
end
|
668
671
|
|
669
672
|
id = ObjectID.from_string(id.to_s)
|
670
|
-
assert_equal "world", @@coll.
|
673
|
+
assert_equal "world", @@coll.find_one(:_id => id)["hello"]
|
671
674
|
end
|
672
675
|
|
673
676
|
def test_save_with_object_that_has_id_but_does_not_actually_exist_in_collection
|
@@ -676,12 +679,12 @@ class DBAPITest < Test::Unit::TestCase
|
|
676
679
|
a = {'_id' => '1', 'hello' => 'world'}
|
677
680
|
@@coll.save(a)
|
678
681
|
assert_equal(1, @@coll.count)
|
679
|
-
assert_equal("world", @@coll.
|
682
|
+
assert_equal("world", @@coll.find_one()["hello"])
|
680
683
|
|
681
684
|
a["hello"] = "mike"
|
682
685
|
@@coll.save(a)
|
683
686
|
assert_equal(1, @@coll.count)
|
684
|
-
assert_equal("mike", @@coll.
|
687
|
+
assert_equal("mike", @@coll.find_one()["hello"])
|
685
688
|
end
|
686
689
|
|
687
690
|
def test_invalid_key_names
|
@@ -690,32 +693,32 @@ class DBAPITest < Test::Unit::TestCase
|
|
690
693
|
@@coll.insert({"hello" => "world"})
|
691
694
|
@@coll.insert({"hello" => {"hello" => "world"}})
|
692
695
|
|
693
|
-
assert_raise
|
696
|
+
assert_raise InvalidName do
|
694
697
|
@@coll.insert({"$hello" => "world"})
|
695
698
|
end
|
696
|
-
assert_raise
|
699
|
+
assert_raise InvalidName do
|
697
700
|
@@coll.insert({"hello" => {"$hello" => "world"}})
|
698
701
|
end
|
699
702
|
|
700
703
|
@@coll.insert({"he$llo" => "world"})
|
701
704
|
@@coll.insert({"hello" => {"hell$o" => "world"}})
|
702
705
|
|
703
|
-
assert_raise
|
706
|
+
assert_raise InvalidName do
|
704
707
|
@@coll.insert({".hello" => "world"})
|
705
708
|
end
|
706
|
-
assert_raise
|
709
|
+
assert_raise InvalidName do
|
707
710
|
@@coll.insert({"hello" => {".hello" => "world"}})
|
708
711
|
end
|
709
|
-
assert_raise
|
712
|
+
assert_raise InvalidName do
|
710
713
|
@@coll.insert({"hello." => "world"})
|
711
714
|
end
|
712
|
-
assert_raise
|
715
|
+
assert_raise InvalidName do
|
713
716
|
@@coll.insert({"hello" => {"hello." => "world"}})
|
714
717
|
end
|
715
|
-
assert_raise
|
718
|
+
assert_raise InvalidName do
|
716
719
|
@@coll.insert({"hel.lo" => "world"})
|
717
720
|
end
|
718
|
-
assert_raise
|
721
|
+
assert_raise InvalidName do
|
719
722
|
@@coll.insert({"hello" => {"hel.lo" => "world"}})
|
720
723
|
end
|
721
724
|
|
@@ -723,22 +726,22 @@ class DBAPITest < Test::Unit::TestCase
|
|
723
726
|
end
|
724
727
|
|
725
728
|
def test_collection_names
|
726
|
-
assert_raise
|
729
|
+
assert_raise TypeError do
|
727
730
|
@@db.collection(5)
|
728
731
|
end
|
729
|
-
assert_raise
|
732
|
+
assert_raise InvalidName do
|
730
733
|
@@db.collection("")
|
731
734
|
end
|
732
|
-
assert_raise
|
735
|
+
assert_raise InvalidName do
|
733
736
|
@@db.collection("te$t")
|
734
737
|
end
|
735
|
-
assert_raise
|
738
|
+
assert_raise InvalidName do
|
736
739
|
@@db.collection(".test")
|
737
740
|
end
|
738
|
-
assert_raise
|
741
|
+
assert_raise InvalidName do
|
739
742
|
@@db.collection("test.")
|
740
743
|
end
|
741
|
-
assert_raise
|
744
|
+
assert_raise InvalidName do
|
742
745
|
@@db.collection("tes..t")
|
743
746
|
end
|
744
747
|
end
|
@@ -749,22 +752,22 @@ class DBAPITest < Test::Unit::TestCase
|
|
749
752
|
a = @@db.collection("foo")
|
750
753
|
b = @@db.collection("bar")
|
751
754
|
|
752
|
-
assert_raise
|
755
|
+
assert_raise TypeError do
|
753
756
|
a.rename(5)
|
754
757
|
end
|
755
|
-
assert_raise
|
758
|
+
assert_raise InvalidName do
|
756
759
|
a.rename("")
|
757
760
|
end
|
758
|
-
assert_raise
|
761
|
+
assert_raise InvalidName do
|
759
762
|
a.rename("te$t")
|
760
763
|
end
|
761
|
-
assert_raise
|
764
|
+
assert_raise InvalidName do
|
762
765
|
a.rename(".test")
|
763
766
|
end
|
764
|
-
assert_raise
|
767
|
+
assert_raise InvalidName do
|
765
768
|
a.rename("test.")
|
766
769
|
end
|
767
|
-
assert_raise
|
770
|
+
assert_raise InvalidName do
|
768
771
|
a.rename("tes..t")
|
769
772
|
end
|
770
773
|
|
data/tests/test_mongo.rb
CHANGED
@@ -17,6 +17,17 @@ class MongoTest < Test::Unit::TestCase
|
|
17
17
|
@mongo.db('ruby-mongo-test').error
|
18
18
|
end
|
19
19
|
|
20
|
+
def test_invalid_database_names
|
21
|
+
assert_raise TypeError do @mongo.db(4) end
|
22
|
+
|
23
|
+
assert_raise InvalidName do @mongo.db('') end
|
24
|
+
assert_raise InvalidName do @mongo.db('te$t') end
|
25
|
+
assert_raise InvalidName do @mongo.db('te.t') end
|
26
|
+
assert_raise InvalidName do @mongo.db('te\\t') end
|
27
|
+
assert_raise InvalidName do @mongo.db('te/t') end
|
28
|
+
assert_raise InvalidName do @mongo.db('te st') end
|
29
|
+
end
|
30
|
+
|
20
31
|
def test_database_info
|
21
32
|
@mongo.drop_database('ruby-mongo-info-test')
|
22
33
|
@mongo.db('ruby-mongo-info-test').collection('info-test').insert('a' => 1)
|
data/tests/test_ordered_hash.rb
CHANGED
@@ -12,6 +12,15 @@ class OrderedHashTest < Test::Unit::TestCase
|
|
12
12
|
@ordered_keys = %w(c a z)
|
13
13
|
end
|
14
14
|
|
15
|
+
def test_initialize
|
16
|
+
a = OrderedHash.new
|
17
|
+
a['x'] = 1
|
18
|
+
a['y'] = 2
|
19
|
+
|
20
|
+
b = OrderedHash['x' => 1, 'y' => 2]
|
21
|
+
assert_equal a, b
|
22
|
+
end
|
23
|
+
|
15
24
|
def test_empty
|
16
25
|
assert_equal [], OrderedHash.new.keys
|
17
26
|
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.12"
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jim Menard
|
@@ -49,6 +49,7 @@ files:
|
|
49
49
|
- lib/mongo/gridfs/chunk.rb
|
50
50
|
- lib/mongo/gridfs/grid_store.rb
|
51
51
|
- lib/mongo/gridfs.rb
|
52
|
+
- lib/mongo/errors.rb
|
52
53
|
- lib/mongo/message/get_more_message.rb
|
53
54
|
- lib/mongo/message/insert_message.rb
|
54
55
|
- lib/mongo/message/kill_cursors_message.rb
|
@@ -121,6 +122,7 @@ test_files:
|
|
121
122
|
- tests/test_bson.rb
|
122
123
|
- tests/test_byte_buffer.rb
|
123
124
|
- tests/test_chunk.rb
|
125
|
+
- tests/test_collection.rb
|
124
126
|
- tests/test_cursor.rb
|
125
127
|
- tests/test_db.rb
|
126
128
|
- tests/test_db_api.rb
|