mongo 0.0.3 → 0.0.4

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.
@@ -49,6 +49,21 @@ be running, of course.
49
49
  See also the test code, especially tests/test_db_api.rb.
50
50
 
51
51
 
52
+ = Notes
53
+
54
+ == String Encoding
55
+
56
+ The BSON ("Binary JSON") format used to communicate with Mongo requires that
57
+ strings be UTF-8 (http://en.wikipedia.org/wiki/UTF-8).
58
+
59
+ Ruby 1.9 has built-in character encoding support. All strings sent to Mongo
60
+ and received from Mongo are converted to UTF-8 when necessary, and strings
61
+ read from Mongo will have their character encodings set to UTF-8.
62
+
63
+ When used with Ruby 1.8, the bytes in each string are written to and read from
64
+ Mongo as-is. If the string is ASCII all is well, because ASCII is a subset of
65
+ UTF-8. If the string is not ASCII then it may not be a well-formed UTF-8 string.
66
+
52
67
  = Testing
53
68
 
54
69
  If you have the source code, you can run the tests.
data/Rakefile CHANGED
@@ -7,7 +7,7 @@ require 'rake/gempackagetask'
7
7
  require 'rake/contrib/rubyforgepublisher'
8
8
 
9
9
  GEM = "mongo"
10
- GEM_VERSION = '0.0.3'
10
+ GEM_VERSION = '0.0.4'
11
11
  SUMMARY = 'Simple pure-Ruby driver for the 10gen Mongo DB'
12
12
  DESCRIPTION = 'This is a simple pure-Ruby driver for the 10gen Mongo DB. For more information about Mongo, see http://www.mongodb.org.'
13
13
  AUTHOR = 'Jim Menard'
@@ -1,8 +1,10 @@
1
+ require 'mongo/types/binary'
2
+ require 'mongo/types/dbref'
3
+ require 'mongo/types/objectid'
4
+ require 'mongo/types/regexp_of_holding'
5
+ require 'mongo/types/undefined'
6
+
1
7
  require 'mongo/mongo'
2
- require 'mongo/objectid'
3
- require 'mongo/dbref'
4
- require 'mongo/binary'
5
- require 'mongo/undefined'
6
8
  require 'mongo/message'
7
9
  require 'mongo/db'
8
10
  require 'mongo/cursor'
@@ -66,7 +66,7 @@ module XGen
66
66
  # Return an array contining current profiling information from the
67
67
  # database.
68
68
  def profiling_info
69
- @db.query(DB::SYSTEM_PROFILE_COLLECTION, Query.new({})).to_a
69
+ @db.query(Collection.new(@db, DB::SYSTEM_PROFILE_COLLECTION), Query.new({})).to_a
70
70
  end
71
71
 
72
72
  # Validate a named collection by raising an exception if there is a
@@ -23,13 +23,22 @@ module XGen
23
23
  # A named collection of records in a database.
24
24
  class Collection
25
25
 
26
- attr_reader :db, :name
26
+ attr_reader :db, :name, :hint_fields
27
27
 
28
28
  def initialize(db, name)
29
29
  @db = db
30
30
  @name = name
31
31
  end
32
32
 
33
+ # Set hint fields to use and return +self+. hint_fields may be a
34
+ # single field name or array of field names. May be +nil+. If no hint
35
+ # fields are specified, the ones in the collection are used if they
36
+ # exist.
37
+ def hint(hint_fields)
38
+ @hint_fileds = hint_fileds
39
+ self
40
+ end
41
+
33
42
  # Return records that match a +selector+ hash. See Mongo docs for
34
43
  # details.
35
44
  #
@@ -47,7 +56,7 @@ module XGen
47
56
  limit = options.delete(:limit) || 0
48
57
  sort = options.delete(:sort)
49
58
  raise RuntimeError, "Unknown options [#{options.inspect}]" unless options.empty?
50
- @db.query(@name, Query.new(selector, fields, offset, limit, sort))
59
+ @db.query(self, Query.new(selector, fields, offset, limit, sort))
51
60
  end
52
61
 
53
62
  # Insert +objects+, which are hashes. "<<" is aliased to this method.
@@ -29,12 +29,26 @@ module XGen
29
29
 
30
30
  RESPONSE_HEADER_SIZE = 20
31
31
 
32
- def initialize(db, collection, num_to_return=0)
33
- @db, @collection, @num_to_return = db, collection, num_to_return
32
+ attr_reader :db, :collection, :query
33
+
34
+ def initialize(db, collection, query)
35
+ @db, @collection, @query = db, collection, query
36
+ @num_to_return = @query.number_to_return || 0
34
37
  @cache = []
35
38
  @closed = false
36
39
  @can_call_to_a = true
37
- read_all
40
+ @query_run = false
41
+ end
42
+
43
+ def closed?; @closed; end
44
+
45
+ # Set hint fields to use and return +self+. hint_fields may be a
46
+ # single field name or array of field names. May be +nil+. If no hint
47
+ # fields are specified, the ones in the collection are used if they
48
+ # exist.
49
+ def hint(hint_fields)
50
+ @hint_fields = hint_fields
51
+ self
38
52
  end
39
53
 
40
54
  # Return +true+ if there are more records to retrieve. We do not check
@@ -100,9 +114,20 @@ module XGen
100
114
  @rows
101
115
  end
102
116
 
117
+ # Returns an explain plan record.
118
+ def explain
119
+ sel = OrderedHash.new
120
+ sel['query'] = @query.selector
121
+ sel['$explain'] = true
122
+ c = Cursor.new(@db, @collection, Query.new(sel))
123
+ e = c.next_object
124
+ c.close
125
+ e
126
+ end
127
+
103
128
  # Close the cursor.
104
129
  def close
105
- @db.send_to_db(KillCursorMessage(@cursor_id)) if @cursor_id
130
+ @db.send_to_db(KillCursorsMessage.new(@cursor_id)) if @cursor_id
106
131
  @cache = []
107
132
  @cursor_id = 0
108
133
  @closed = true
@@ -146,6 +171,7 @@ module XGen
146
171
  private
147
172
 
148
173
  def next_object_on_wire
174
+ send_query_if_needed
149
175
  # if @n_remaining is 0 but we have a non-zero cursor, there are more
150
176
  # to fetch, so do a GetMore operation, but don't do it here - do it
151
177
  # when someone pulls an object out of the cache and it's empty
@@ -154,8 +180,9 @@ module XGen
154
180
  end
155
181
 
156
182
  def refill_via_get_more
183
+ send_query_if_needed
157
184
  return if @cursor_id == 0
158
- @db.send_to_db(GetMoreMessage.new(@db.name, @collection, @cursor_id))
185
+ @db.send_to_db(GetMoreMessage.new(@db.name, @collection.name, @cursor_id))
159
186
  read_all
160
187
  end
161
188
 
@@ -170,6 +197,27 @@ module XGen
170
197
  BSON.new(@db).deserialize(buf)
171
198
  end
172
199
 
200
+ def send_query_if_needed
201
+ # Run query first time we request an object from the wire
202
+ unless @query_run
203
+ hints = @hint_fields || @collection.hint_fields
204
+ hints = [hints] if hints.kind_of?(String)
205
+ query = if hints
206
+ h = {}
207
+ hints.each { |field| h[field] = 1 }
208
+ sel = OrderedHash.new
209
+ sel['query'] = @query.selector
210
+ sel['$hint'] = h
211
+ Query.new(sel)
212
+ else
213
+ @query
214
+ end
215
+ @db.send_query_message(QueryMessage.new(@db.name, @collection.name, query))
216
+ @query_run = true
217
+ read_all
218
+ end
219
+ end
220
+
173
221
  def to_s
174
222
  "DBResponse(flags=#@result_flags, cursor_id=#@cursor_id, start=#@starting_from, n_returned=#@n_returned)"
175
223
  end
@@ -177,4 +225,3 @@ module XGen
177
225
  end
178
226
  end
179
227
  end
180
-
@@ -49,6 +49,8 @@ module XGen
49
49
  # The name of the database.
50
50
  attr_reader :name
51
51
 
52
+ attr_reader :host, :port
53
+
52
54
  # The database's socket. For internal use only.
53
55
  attr_reader :socket
54
56
 
@@ -82,7 +84,7 @@ module XGen
82
84
  def collections_info(coll_name=nil)
83
85
  selector = {}
84
86
  selector[:name] = full_coll_name(coll_name) if coll_name
85
- query(SYSTEM_NAMESPACE_COLLECTION, Query.new(selector))
87
+ query(Collection.new(self, SYSTEM_NAMESPACE_COLLECTION), Query.new(selector))
86
88
  end
87
89
 
88
90
  # Create a collection. If +strict+ is false, will return existing or
@@ -151,6 +153,20 @@ module XGen
151
153
  ok?(doc) && is_master.kind_of?(Numeric) && is_master.to_i == 1
152
154
  end
153
155
 
156
+ # Returns a string of the form "host:port" that points to the master
157
+ # database. Works even if this is the master database.
158
+ def master
159
+ doc = db_command(:ismaster => 1)
160
+ is_master = doc['ismaster']
161
+ raise "Error retrieving master database" unless ok?(doc) && is_master.kind_of?(Numeric)
162
+ case is_master.to_i
163
+ when 1
164
+ "#@host:#@port"
165
+ else
166
+ doc['remote']
167
+ end
168
+ end
169
+
154
170
  # Close the connection to the database.
155
171
  def close
156
172
  @socket.close
@@ -161,12 +177,19 @@ module XGen
161
177
  send_to_db(MsgMessage.new(msg))
162
178
  end
163
179
 
164
- # Send a Query to +collection_name+ and return a Cursor over the
165
- # results.
166
- def query(collection_name, query)
180
+ # Returns a Cursor over the query results.
181
+ #
182
+ # Note that the query gets sent lazily; the cursor calls
183
+ # #send_query_message when needed. If the caller never requests an
184
+ # object from the cursor, the query never gets sent.
185
+ def query(collection, query)
186
+ Cursor.new(self, collection, query)
187
+ end
188
+
189
+ # Used by a Cursor to lazily send the query to the database.
190
+ def send_query_message(query_message)
167
191
  @semaphore.synchronize {
168
- send_to_db(QueryMessage.new(@name, collection_name, query))
169
- Cursor.new(self, collection_name, query.number_to_return)
192
+ send_to_db(query_message)
170
193
  }
171
194
  end
172
195
 
@@ -233,7 +256,7 @@ module XGen
233
256
  # :ns :: Namespace; same as +collection_name+.
234
257
  def index_information(collection_name)
235
258
  sel = {:ns => full_coll_name(collection_name)}
236
- query(SYSTEM_INDEX_COLLECTION, Query.new(sel)).collect { |row|
259
+ query(Collection.new(self, SYSTEM_INDEX_COLLECTION), Query.new(sel)).collect { |row|
237
260
  h = {:name => row['name']}
238
261
  raise "Name of index on return from db was nil. Coll = #{full_coll_name(collection_name)}" unless h[:name]
239
262
 
@@ -298,7 +321,7 @@ module XGen
298
321
 
299
322
  q = Query.new(selector)
300
323
  q.number_to_return = 1
301
- query(SYSTEM_COMMAND_COLLECTION, q).next_object
324
+ query(Collection.new(self, SYSTEM_COMMAND_COLLECTION), q).next_object
302
325
  end
303
326
 
304
327
  end
@@ -8,8 +8,11 @@ module XGen
8
8
 
9
9
  class QueryMessage < Message
10
10
 
11
+ attr_reader :query
12
+
11
13
  def initialize(db_name, collection_name, query)
12
14
  super(OP_QUERY)
15
+ @query = query
13
16
  write_int(0)
14
17
  write_string("#{db_name}.#{collection_name}")
15
18
  write_int(query.number_to_skip)
File without changes
File without changes
@@ -0,0 +1,44 @@
1
+ # --
2
+ # Copyright (C) 2008-2009 10gen Inc.
3
+ #
4
+ # This program is free software: you can redistribute it and/or modify it
5
+ # under the terms of the GNU Affero General Public License, version 3, as
6
+ # published by the Free Software Foundation.
7
+ #
8
+ # This program is distributed in the hope that it will be useful, but WITHOUT
9
+ # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10
+ # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License
11
+ # for more details.
12
+ #
13
+ # You should have received a copy of the GNU Affero General Public License
14
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
15
+ # ++
16
+
17
+ module XGen
18
+ module Mongo
19
+ module Driver
20
+
21
+ # A Regexp that can hold on to extra options and ignore them. Mongo
22
+ # regexes may contain option characters beyond 'i', 'm', and 'x'. (Note
23
+ # that Mongo only uses those three, but that regexes coming from other
24
+ # languages may store different option characters.)
25
+ #
26
+ # Note that you do not have to use this class at all if you wish to
27
+ # store regular expressions in Mongo. The Mongo and Ruby regex option
28
+ # flags are the same. Storing regexes is discouraged, in any case.
29
+ class RegexpOfHolding < Regexp
30
+
31
+ attr_accessor :extra_options_str
32
+
33
+ # +str+ and +options+ are the same as Regexp. +extra_options_str+
34
+ # contains all the other flags that were in Mongo but we do not use or
35
+ # understand.
36
+ def initialize(str, options, extra_options_str)
37
+ super(str, options)
38
+ @extra_options_str = extra_options_str
39
+ end
40
+ end
41
+
42
+ end
43
+ end
44
+ end
@@ -17,8 +17,11 @@
17
17
  require 'base64'
18
18
  require 'mongo/util/byte_buffer'
19
19
  require 'mongo/util/ordered_hash'
20
- require 'mongo/objectid'
21
- require 'mongo/dbref'
20
+ require 'mongo/types/binary'
21
+ require 'mongo/types/dbref'
22
+ require 'mongo/types/objectid'
23
+ require 'mongo/types/regexp_of_holding'
24
+ require 'mongo/types/undefined'
22
25
 
23
26
  # A BSON seralizer/deserializer.
24
27
  class BSON
@@ -43,8 +46,18 @@ class BSON
43
46
  NUMBER_INT = 16
44
47
  MAXKEY = 127
45
48
 
49
+ if RUBY_VERSION >= '1.9'
50
+ def self.to_utf8(str)
51
+ str.encode("utf-8")
52
+ end
53
+ else
54
+ def self.to_utf8(str)
55
+ str # TODO punt for now
56
+ end
57
+ end
58
+
46
59
  def self.serialize_cstr(buf, val)
47
- buf.put_array(val.to_s.unpack("C*") + [0])
60
+ buf.put_array(to_utf8(val.to_s).unpack("C*") + [0])
48
61
  end
49
62
 
50
63
  def initialize(db=nil)
@@ -67,7 +80,7 @@ class BSON
67
80
  obj.each {|k, v|
68
81
  type = bson_type(v, k)
69
82
  case type
70
- when STRING, CODE
83
+ when STRING, CODE, SYMBOL
71
84
  serialize_string_element(@buf, k, v, type)
72
85
  when NUMBER, NUMBER_INT
73
86
  serialize_number_element(@buf, k, v, type)
@@ -87,8 +100,6 @@ class BSON
87
100
  serialize_null_element(@buf, k)
88
101
  when REF
89
102
  serialize_dbref_element(@buf, k, v)
90
- when SYMBOL
91
- serialize_symbol_element(@buf, k, v)
92
103
  when BINARY
93
104
  serialize_binary_element(@buf, k, v)
94
105
  when UNDEFINED
@@ -118,6 +129,9 @@ class BSON
118
129
  when STRING, CODE
119
130
  key = deserialize_cstr(@buf)
120
131
  doc[key] = deserialize_string_data(@buf)
132
+ when SYMBOL
133
+ key = deserialize_cstr(@buf)
134
+ doc[key] = deserialize_string_data(@buf).intern
121
135
  when NUMBER
122
136
  key = deserialize_cstr(@buf)
123
137
  doc[key] = deserialize_number_data(@buf)
@@ -151,9 +165,6 @@ class BSON
151
165
  when REF
152
166
  key = deserialize_cstr(@buf)
153
167
  doc[key] = deserialize_dbref_data(@buf, key, parent)
154
- when SYMBOL
155
- key = deserialize_cstr(@buf)
156
- doc[key] = deserialize_symbol_data(@buf)
157
168
  when BINARY
158
169
  key = deserialize_cstr(@buf)
159
170
  doc[key] = deserialize_binary_data(@buf)
@@ -170,6 +181,7 @@ class BSON
170
181
  doc
171
182
  end
172
183
 
184
+ # For debugging.
173
185
  def hex_dump
174
186
  str = ''
175
187
  @buf.to_a.each_with_index { |b,i|
@@ -221,13 +233,18 @@ class BSON
221
233
  options |= Regexp::IGNORECASE if options_str.include?('i')
222
234
  options |= Regexp::MULTILINE if options_str.include?('m')
223
235
  options |= Regexp::EXTENDED if options_str.include?('x')
224
- Regexp.new(str, options)
236
+ options_str.gsub!(/[imx]/, '') # Now remove the three we understand
237
+ XGen::Mongo::Driver::RegexpOfHolding.new(str, options, options_str)
225
238
  end
226
239
 
227
240
  def deserialize_string_data(buf)
228
241
  len = buf.get_int
229
242
  bytes = buf.get(len)
230
- bytes[0..-2].pack("C*")
243
+ str = bytes[0..-2].pack("C*")
244
+ if RUBY_VERSION >= '1.9'
245
+ str.force_encoding("utf-8")
246
+ end
247
+ str
231
248
  end
232
249
 
233
250
  def deserialize_oid_data(buf)
@@ -240,10 +257,6 @@ class BSON
240
257
  XGen::Mongo::Driver::DBRef.new(parent, key, @db, ns, oid)
241
258
  end
242
259
 
243
- def deserialize_symbol_data(buf)
244
- deserialize_cstr(buf).intern
245
- end
246
-
247
260
  def deserialize_binary_data(buf)
248
261
  len = buf.get_int
249
262
  bytes = buf.get(len)
@@ -268,12 +281,6 @@ class BSON
268
281
  buf.put_array(val.object_id.to_a)
269
282
  end
270
283
 
271
- def serialize_symbol_element(buf, key, val)
272
- buf.put(SYMBOL)
273
- self.class.serialize_cstr(buf, key)
274
- self.class.serialize_cstr(buf, val)
275
- end
276
-
277
284
  def serialize_binary_element(buf, key, val)
278
285
  buf.put(BINARY)
279
286
  self.class.serialize_cstr(buf, key)
@@ -342,7 +349,9 @@ class BSON
342
349
  options_str << 'i' if ((options & Regexp::IGNORECASE) != 0)
343
350
  options_str << 'm' if ((options & Regexp::MULTILINE) != 0)
344
351
  options_str << 'x' if ((options & Regexp::EXTENDED) != 0)
345
- self.class.serialize_cstr(buf, options_str)
352
+ options_str << val.extra_options_str if val.respond_to?(:extra_options_str)
353
+ # Must store option chars in alphabetical order
354
+ self.class.serialize_cstr(buf, options_str.split(//).sort.uniq.join)
346
355
  end
347
356
 
348
357
  def serialize_oid_element(buf, key, val)
@@ -379,6 +388,9 @@ class BSON
379
388
  break if b == 0
380
389
  chars << b.chr
381
390
  end
391
+ if RUBY_VERSION >= '1.9'
392
+ chars.force_encoding("utf-8") # Mongo stores UTF-8
393
+ end
382
394
  chars
383
395
  end
384
396
 
@@ -15,8 +15,14 @@
15
15
  # ++
16
16
 
17
17
  # A hash in which the order of keys are preserved.
18
+ #
19
+ # Under Ruby 1.9 and greater, this class has no added methods because Ruby's
20
+ # Hash already keeps its keys ordered by order of insertion.
18
21
  class OrderedHash < Hash
19
22
 
23
+ # We only need the body of this class if the RUBY_VERSION is before 1.9
24
+ if RUBY_VERSION < '1.9'
25
+
20
26
  attr_accessor :ordered_keys
21
27
 
22
28
  def keys
@@ -57,4 +63,6 @@ class OrderedHash < Hash
57
63
  str << '}'
58
64
  end
59
65
 
66
+ end # Ruby before 1.9
67
+
60
68
  end
@@ -59,7 +59,26 @@ class BSONTest < Test::Unit::TestCase
59
59
  def test_regex
60
60
  doc = {'doc' => /foobar/i}
61
61
  @b.serialize(doc)
62
- assert_equal doc, @b.deserialize
62
+ doc2 = @b.deserialize
63
+ assert_equal doc, doc2
64
+
65
+ r = doc2['doc']
66
+ assert_kind_of XGen::Mongo::Driver::RegexpOfHolding, r
67
+ assert_equal '', r.extra_options_str
68
+
69
+ r.extra_options_str << 'zywcab'
70
+ assert_equal 'zywcab', r.extra_options_str
71
+
72
+ b = BSON.new
73
+ doc = {'doc' => r}
74
+ b.serialize(doc)
75
+ doc2 = nil
76
+ doc2 = b.deserialize
77
+ assert_equal doc, doc2
78
+
79
+ r = doc2['doc']
80
+ assert_kind_of XGen::Mongo::Driver::RegexpOfHolding, r
81
+ assert_equal 'abcwyz', r.extra_options_str # must be sorted
63
82
  end
64
83
 
65
84
  def test_boolean
@@ -0,0 +1,63 @@
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 XGen::Mongo::Driver
9
+
10
+ def setup
11
+ host = ENV['MONGO_RUBY_DRIVER_HOST'] || 'localhost'
12
+ port = ENV['MONGO_RUBY_DRIVER_PORT'] || Mongo::DEFAULT_PORT
13
+ @db = Mongo.new(host, port).db('ruby-mongo-test')
14
+ @coll = @db.collection('test')
15
+ @coll.clear
16
+ @r1 = @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 unless @coll == nil || @db.socket.closed?
22
+ end
23
+
24
+ def test_explain
25
+ cursor = @coll.find('a' => 1)
26
+ explaination = cursor.explain
27
+ assert_not_nil explaination['cursor']
28
+ assert_kind_of Numeric, explaination['n']
29
+ assert_kind_of Numeric, explaination['millis']
30
+ assert_kind_of Numeric, explaination['nscanned']
31
+ end
32
+
33
+ def test_close_no_query_sent
34
+ begin
35
+ cursor = @coll.find('a' => 1)
36
+ cursor.close
37
+ assert cursor.closed?
38
+ rescue => ex
39
+ fail ex.to_s
40
+ end
41
+ end
42
+
43
+ def test_close_after_query_sent
44
+ begin
45
+ cursor = @coll.find('a' => 1)
46
+ cursor.next_object
47
+ cursor.close
48
+ assert cursor.closed?
49
+ rescue => ex
50
+ fail ex.to_s
51
+ end
52
+ end
53
+
54
+ def test_hint
55
+ begin
56
+ cursor = @coll.find('a' => 1).hint('a')
57
+ assert_equal 1, cursor.to_a.size
58
+ rescue => ex
59
+ fail ex.to_s
60
+ end
61
+ end
62
+
63
+ end
@@ -354,4 +354,8 @@ class DBAPITest < Test::Unit::TestCase
354
354
  assert @db.master?
355
355
  end
356
356
 
357
+ def test_master
358
+ assert_equal "#{@db.host}:#{@db.port}", @db.master
359
+ end
360
+
357
361
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mongo
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jim Menard
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-01-12 00:00:00 -05:00
12
+ date: 2009-01-14 00:00:00 -05:00
13
13
  default_executable:
14
14
  dependencies: []
15
15
 
@@ -25,11 +25,9 @@ files:
25
25
  - bin/mongo_console
26
26
  - bin/validate
27
27
  - lib/mongo/admin.rb
28
- - lib/mongo/binary.rb
29
28
  - lib/mongo/collection.rb
30
29
  - lib/mongo/cursor.rb
31
30
  - lib/mongo/db.rb
32
- - lib/mongo/dbref.rb
33
31
  - lib/mongo/message/get_more_message.rb
34
32
  - lib/mongo/message/insert_message.rb
35
33
  - lib/mongo/message/kill_cursors_message.rb
@@ -42,9 +40,12 @@ files:
42
40
  - lib/mongo/message/update_message.rb
43
41
  - lib/mongo/message.rb
44
42
  - lib/mongo/mongo.rb
45
- - lib/mongo/objectid.rb
46
43
  - lib/mongo/query.rb
47
- - lib/mongo/undefined.rb
44
+ - lib/mongo/types/binary.rb
45
+ - lib/mongo/types/dbref.rb
46
+ - lib/mongo/types/objectid.rb
47
+ - lib/mongo/types/regexp_of_holding.rb
48
+ - lib/mongo/types/undefined.rb
48
49
  - lib/mongo/util/bson.rb
49
50
  - lib/mongo/util/byte_buffer.rb
50
51
  - lib/mongo/util/ordered_hash.rb
@@ -53,6 +54,7 @@ files:
53
54
  - tests/test_admin.rb
54
55
  - tests/test_bson.rb
55
56
  - tests/test_byte_buffer.rb
57
+ - tests/test_cursor.rb
56
58
  - tests/test_db_api.rb
57
59
  - tests/test_db_connection.rb
58
60
  - tests/test_message.rb