mongo 1.3.0 → 1.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.md +8 -7
- data/docs/HISTORY.md +19 -0
- data/lib/mongo.rb +1 -1
- data/lib/mongo/collection.rb +24 -14
- data/lib/mongo/connection.rb +27 -3
- data/lib/mongo/cursor.rb +25 -7
- data/lib/mongo/db.rb +30 -20
- data/lib/mongo/gridfs/grid.rb +2 -1
- data/lib/mongo/gridfs/grid_file_system.rb +1 -0
- data/lib/mongo/gridfs/grid_io.rb +56 -46
- data/lib/mongo/repl_set_connection.rb +1 -0
- data/test/bson/bson_test.rb +5 -0
- data/test/bson/ordered_hash_test.rb +7 -1
- data/test/db_api_test.rb +12 -0
- data/test/db_test.rb +35 -7
- data/test/grid_file_system_test.rb +16 -0
- data/test/grid_io_test.rb +18 -0
- data/test/grid_test.rb +59 -1
- data/test/replica_sets/connect_test.rb +5 -1
- data/test/replica_sets/query_secondaries.rb +15 -3
- data/test/tools/repl_set_manager.rb +3 -3
- metadata +138 -211
data/README.md
CHANGED
@@ -18,17 +18,18 @@ for much more:
|
|
18
18
|
|
19
19
|
require 'rubygems'
|
20
20
|
require 'mongo'
|
21
|
-
include Mongo
|
22
21
|
|
23
|
-
|
24
|
-
|
22
|
+
@conn = Mongo::Connection.new
|
23
|
+
@db = @conn['sample-db']
|
24
|
+
@coll = @db['test']
|
25
25
|
|
26
|
-
coll.remove
|
26
|
+
@coll.remove
|
27
27
|
3.times do |i|
|
28
|
-
coll.insert({'a' => i+1})
|
28
|
+
@coll.insert({'a' => i+1})
|
29
29
|
end
|
30
|
-
|
31
|
-
coll.
|
30
|
+
|
31
|
+
puts "There are #{@coll.count} records. Here they are:"
|
32
|
+
@coll.find.each { |doc| puts doc.inspect }
|
32
33
|
|
33
34
|
# Installation
|
34
35
|
|
data/docs/HISTORY.md
CHANGED
@@ -1,5 +1,24 @@
|
|
1
1
|
# MongoDB Ruby Driver History
|
2
2
|
|
3
|
+
### 1.3.1
|
4
|
+
2011-5-10
|
5
|
+
|
6
|
+
* Fix GridIO#gets infinite loop error (Ryan McGeary)
|
7
|
+
* Fix BSON::OrderedHash#reject! leaving keys with null values (rpt. by Ben Poweski)
|
8
|
+
* Minor semantic fix for OrderedHash#reject!
|
9
|
+
* Fix Mongo::DB to allow symbols in method traversing collection names (rpt. by Chris Griego)
|
10
|
+
* Support new server regex option "s" (dotall). This is folded in with \m in Ruby.
|
11
|
+
* Fix so that Cursor#close hits the right node when :read_secondary is enabled.
|
12
|
+
* Support maxScan, showDiskLoc, and returnKey cursor options.
|
13
|
+
* Make DB#validate_collection compatible with server v1.9.1.
|
14
|
+
* Fix so that GridIO#gets returns local md5 with md5 matches server md5 (Steve Tantra).
|
15
|
+
* Fix bug in BSON::OrderedHash that prevents YAML.load (Ian Warshak).
|
16
|
+
* Fix example from /examples.
|
17
|
+
* Ensure that we do not modify hash arguments by calling Hash#dup when appropriate.
|
18
|
+
* Ensure that JRuby deserializer preserves binary subtypes properly.
|
19
|
+
* Fix for streaming an empty file into GridFS (Daniël van de Burgt).
|
20
|
+
* Minor doc fixes.
|
21
|
+
|
3
22
|
### 1.3.0
|
4
23
|
2011-4-04
|
5
24
|
|
data/lib/mongo.rb
CHANGED
data/lib/mongo/collection.rb
CHANGED
@@ -91,7 +91,7 @@ module Mongo
|
|
91
91
|
# Return a sub-collection of this collection by name. If 'users' is a collection, then
|
92
92
|
# 'users.comments' is a sub-collection of users.
|
93
93
|
#
|
94
|
-
# @param [String] name
|
94
|
+
# @param [String, Symbol] name
|
95
95
|
# the collection to return
|
96
96
|
#
|
97
97
|
# @raise [Mongo::InvalidNSName]
|
@@ -101,7 +101,8 @@ module Mongo
|
|
101
101
|
# the specified sub-collection
|
102
102
|
def [](name)
|
103
103
|
name = "#{self.name}.#{name}"
|
104
|
-
return Collection.new(name, db) if !db.strict? ||
|
104
|
+
return Collection.new(name, db) if !db.strict? ||
|
105
|
+
db.collection_names.include?(name.to_s)
|
105
106
|
raise "Collection #{name} doesn't exist. Currently in strict mode."
|
106
107
|
end
|
107
108
|
|
@@ -147,16 +148,23 @@ module Mongo
|
|
147
148
|
# @option opts [Integer] :limit maximum number of documents to return
|
148
149
|
# @option opts [Array] :sort an array of [key, direction] pairs to sort by. Direction should
|
149
150
|
# be specified as Mongo::ASCENDING (or :ascending / :asc) or Mongo::DESCENDING (or :descending / :desc)
|
150
|
-
# @option opts [String, Array, OrderedHash] :hint hint for query optimizer, usually not necessary if
|
151
|
+
# @option opts [String, Array, OrderedHash] :hint hint for query optimizer, usually not necessary if
|
152
|
+
# using MongoDB > 1.1
|
151
153
|
# @option opts [Boolean] :snapshot (false) if true, snapshot mode will be used for this query.
|
152
154
|
# Snapshot mode assures no duplicates are returned, or objects missed, which were preset at both the start and
|
153
|
-
# end of the query's execution.
|
154
|
-
#
|
155
|
-
#
|
155
|
+
# end of the query's execution.
|
156
|
+
# For details see http://www.mongodb.org/display/DOCS/How+to+do+Snapshotting+in+the+Mongo+Database
|
157
|
+
# @option opts [Boolean] :batch_size (100) the number of documents to returned by the database per
|
158
|
+
# GETMORE operation. A value of 0 will let the database server decide how many results to returns.
|
159
|
+
# This option can be ignored for most use cases.
|
156
160
|
# @option opts [Boolean] :timeout (true) when +true+, the returned cursor will be subject to
|
157
|
-
# the normal cursor timeout behavior of the mongod process. When +false+, the returned cursor will
|
158
|
-
# that disabling timeout will only work when #find is invoked with a block.
|
159
|
-
# close the cursor, as the cursor is explicitly
|
161
|
+
# the normal cursor timeout behavior of the mongod process. When +false+, the returned cursor will
|
162
|
+
# never timeout. Note that disabling timeout will only work when #find is invoked with a block.
|
163
|
+
# This is to prevent any inadvertant failure to close the cursor, as the cursor is explicitly
|
164
|
+
# closed when block code finishes.
|
165
|
+
# @option opts [Integer] :max_scan (nil) Limit the number of items to scan on both collection scans and indexed queries..
|
166
|
+
# @option opts [Boolean] :show_disk_loc (false) Return the disk location of each query result (for debugging).
|
167
|
+
# @option opts [Boolean] :return_key (false) Return the index key used to obtain the result (for debugging).
|
160
168
|
# @option opts [Block] :transformer (nil) a block for tranforming returned documents.
|
161
169
|
# This is normally used by object mappers to convert each returned document to an instance of a class.
|
162
170
|
#
|
@@ -168,6 +176,7 @@ module Mongo
|
|
168
176
|
#
|
169
177
|
# @core find find-instance_method
|
170
178
|
def find(selector={}, opts={})
|
179
|
+
opts = opts.dup
|
171
180
|
fields = opts.delete(:fields)
|
172
181
|
fields = ["_id"] if fields && fields.empty?
|
173
182
|
skip = opts.delete(:skip) || skip || 0
|
@@ -385,7 +394,7 @@ module Mongo
|
|
385
394
|
if safe
|
386
395
|
@connection.send_message_with_safe_check(Mongo::Constants::OP_UPDATE, message, @db.name, nil, safe)
|
387
396
|
else
|
388
|
-
@connection.send_message(Mongo::Constants::OP_UPDATE, message
|
397
|
+
@connection.send_message(Mongo::Constants::OP_UPDATE, message)
|
389
398
|
end
|
390
399
|
end
|
391
400
|
end
|
@@ -433,8 +442,9 @@ module Mongo
|
|
433
442
|
#
|
434
443
|
# @core indexes create_index-instance_method
|
435
444
|
def create_index(spec, opts={})
|
436
|
-
opts[:dropDups] = opts
|
445
|
+
opts[:dropDups] = opts[:drop_dups] if opts[:drop_dups]
|
437
446
|
field_spec = parse_index_spec(spec)
|
447
|
+
opts = opts.dup
|
438
448
|
name = opts.delete(:name) || generate_index_name(field_spec)
|
439
449
|
name = name.to_s if name
|
440
450
|
|
@@ -462,7 +472,7 @@ module Mongo
|
|
462
472
|
now = Time.now.utc.to_i
|
463
473
|
field_spec = parse_index_spec(spec)
|
464
474
|
|
465
|
-
name = opts
|
475
|
+
name = opts[:name] || generate_index_name(field_spec)
|
466
476
|
name = name.to_s if name
|
467
477
|
|
468
478
|
if !@cache[name] || @cache[name] <= now
|
@@ -555,7 +565,7 @@ module Mongo
|
|
555
565
|
def map_reduce(map, reduce, opts={})
|
556
566
|
map = BSON::Code.new(map) unless map.is_a?(BSON::Code)
|
557
567
|
reduce = BSON::Code.new(reduce) unless reduce.is_a?(BSON::Code)
|
558
|
-
raw = opts
|
568
|
+
raw = opts[:raw]
|
559
569
|
|
560
570
|
hash = BSON::OrderedHash.new
|
561
571
|
hash['mapreduce'] = self.name
|
@@ -867,7 +877,7 @@ module Mongo
|
|
867
877
|
if safe
|
868
878
|
@connection.send_message_with_safe_check(Mongo::Constants::OP_INSERT, message, @db.name, nil, safe)
|
869
879
|
else
|
870
|
-
@connection.send_message(Mongo::Constants::OP_INSERT, message
|
880
|
+
@connection.send_message(Mongo::Constants::OP_INSERT, message)
|
871
881
|
end
|
872
882
|
end
|
873
883
|
documents.collect { |o| o[:_id] || o['_id'] }
|
data/lib/mongo/connection.rb
CHANGED
@@ -381,15 +381,36 @@ module Mongo
|
|
381
381
|
# @param [Integer] operation a MongoDB opcode.
|
382
382
|
# @param [BSON::ByteBuffer] message a message to send to the database.
|
383
383
|
#
|
384
|
+
# @option opts [Symbol] :connection (:writer) The connection to which
|
385
|
+
# this message should be sent. Valid options are :writer and :reader.
|
386
|
+
#
|
384
387
|
# @return [Integer] number of bytes sent
|
385
|
-
def send_message(operation, message,
|
388
|
+
def send_message(operation, message, opts={})
|
389
|
+
if opts.is_a?(String)
|
390
|
+
warn "Connection#send_message no longer takes a string log message. " +
|
391
|
+
"Logging is now handled within the Collection and Cursor classes."
|
392
|
+
opts = {}
|
393
|
+
end
|
394
|
+
|
395
|
+
connection = opts.fetch(:connection, :writer)
|
396
|
+
|
386
397
|
begin
|
387
398
|
add_message_headers(message, operation)
|
388
399
|
packed_message = message.to_s
|
389
|
-
|
400
|
+
|
401
|
+
if connection == :writer
|
402
|
+
socket = checkout_writer
|
403
|
+
else
|
404
|
+
socket = checkout_reader
|
405
|
+
end
|
406
|
+
|
390
407
|
send_message_on_socket(packed_message, socket)
|
391
408
|
ensure
|
392
|
-
|
409
|
+
if connection == :writer
|
410
|
+
checkin_writer(socket)
|
411
|
+
else
|
412
|
+
checkin_reader(socket)
|
413
|
+
end
|
393
414
|
end
|
394
415
|
end
|
395
416
|
|
@@ -437,7 +458,10 @@ module Mongo
|
|
437
458
|
#
|
438
459
|
# @param [Integer] operation a MongoDB opcode.
|
439
460
|
# @param [BSON::ByteBuffer] message a message to send to the database.
|
461
|
+
# @param [String] log_message this is currently a no-op and will be removed.
|
440
462
|
# @param [Socket] socket a socket to use in lieu of checking out a new one.
|
463
|
+
# @param [Boolean] command (false) indicate whether this is a command. If this is a command,
|
464
|
+
# the message will be sent to the primary node.
|
441
465
|
#
|
442
466
|
# @return [Array]
|
443
467
|
# An array whose indexes include [0] documents returned, [1] number of document received,
|
data/lib/mongo/cursor.rb
CHANGED
@@ -41,19 +41,31 @@ module Mongo
|
|
41
41
|
@connection = @db.connection
|
42
42
|
@logger = @connection.logger
|
43
43
|
|
44
|
+
# Query selector
|
44
45
|
@selector = opts[:selector] || {}
|
45
|
-
|
46
|
-
|
47
|
-
@limit = opts[:limit] || 0
|
46
|
+
|
47
|
+
# Special operators that form part of $query
|
48
48
|
@order = opts[:order]
|
49
|
+
@explain = opts[:explain]
|
49
50
|
@hint = opts[:hint]
|
50
51
|
@snapshot = opts[:snapshot]
|
52
|
+
@max_scan = opts.fetch(:max_scan, nil)
|
53
|
+
@return_key = opts.fetch(:return_key, nil)
|
54
|
+
@show_disk_loc = opts.fetch(:show_disk_loc, nil)
|
55
|
+
|
56
|
+
# Wire-protocol settings
|
57
|
+
@fields = convert_fields_for_query(opts[:fields])
|
58
|
+
@skip = opts[:skip] || 0
|
59
|
+
@limit = opts[:limit] || 0
|
60
|
+
@tailable = opts[:tailable] || false
|
51
61
|
@timeout = opts.fetch(:timeout, true)
|
52
|
-
|
62
|
+
|
63
|
+
# Use this socket for the query
|
53
64
|
@socket = opts[:socket]
|
54
|
-
|
65
|
+
|
55
66
|
@closed = false
|
56
67
|
@query_run = false
|
68
|
+
|
57
69
|
@transformer = opts[:transformer]
|
58
70
|
batch_size(opts[:batch_size] || 0)
|
59
71
|
|
@@ -284,7 +296,7 @@ module Mongo
|
|
284
296
|
message.put_int(1)
|
285
297
|
message.put_long(@cursor_id)
|
286
298
|
@logger.debug("MONGODB cursor.close #{@cursor_id}") if @logger
|
287
|
-
@connection.send_message(Mongo::Constants::OP_KILL_CURSORS, message,
|
299
|
+
@connection.send_message(Mongo::Constants::OP_KILL_CURSORS, message, :connection => :reader)
|
288
300
|
end
|
289
301
|
@cursor_id = 0
|
290
302
|
@closed = true
|
@@ -320,7 +332,10 @@ module Mongo
|
|
320
332
|
:order => @order,
|
321
333
|
:hint => @hint,
|
322
334
|
:snapshot => @snapshot,
|
323
|
-
:timeout => @timeout
|
335
|
+
:timeout => @timeout,
|
336
|
+
:max_scan => @max_scan,
|
337
|
+
:return_key => @return_key,
|
338
|
+
:show_disk_loc => @show_disk_loc }
|
324
339
|
end
|
325
340
|
|
326
341
|
# Clean output for inspect.
|
@@ -429,6 +444,9 @@ module Mongo
|
|
429
444
|
spec['$hint'] = @hint if @hint && @hint.length > 0
|
430
445
|
spec['$explain'] = true if @explain
|
431
446
|
spec['$snapshot'] = true if @snapshot
|
447
|
+
spec['$maxscan'] = @max_scan if @max_scan
|
448
|
+
spec['$returnKey'] = true if @return_key
|
449
|
+
spec['$showDiskLoc'] = true if @show_disk_loc
|
432
450
|
spec
|
433
451
|
end
|
434
452
|
|
data/lib/mongo/db.rb
CHANGED
@@ -251,26 +251,28 @@ module Mongo
|
|
251
251
|
# new collection. If +strict+ is true, will raise an error if
|
252
252
|
# collection +name+ already exists.
|
253
253
|
#
|
254
|
-
# @param [String] name the name of the new collection.
|
254
|
+
# @param [String, Symbol] name the name of the new collection.
|
255
255
|
#
|
256
256
|
# @option opts [Boolean] :capped (False) created a capped collection.
|
257
257
|
#
|
258
|
-
# @option opts [Integer] :size (Nil) If +capped+ is +true+,
|
259
|
-
#
|
258
|
+
# @option opts [Integer] :size (Nil) If +capped+ is +true+,
|
259
|
+
# specifies the maximum number of bytes for the capped collection.
|
260
|
+
# If +false+, specifies the number of bytes allocated
|
260
261
|
# for the initial extent of the collection.
|
261
262
|
#
|
262
|
-
# @option opts [Integer] :max (Nil) If +capped+ is +true+, indicates
|
263
|
-
# in a capped collection.
|
263
|
+
# @option opts [Integer] :max (Nil) If +capped+ is +true+, indicates
|
264
|
+
# the maximum number of records in a capped collection.
|
264
265
|
#
|
265
|
-
# @raise [MongoDBError] raised under two conditions:
|
266
|
+
# @raise [MongoDBError] raised under two conditions:
|
267
|
+
# either we're in +strict+ mode and the collection
|
266
268
|
# already exists or collection creation fails on the server.
|
267
269
|
#
|
268
270
|
# @return [Mongo::Collection]
|
269
271
|
def create_collection(name, opts={})
|
270
|
-
|
271
|
-
if collection_names.include?(name)
|
272
|
+
if collection_names.include?(name.to_s)
|
272
273
|
if strict?
|
273
|
-
raise MongoDBError, "Collection #{name} already exists.
|
274
|
+
raise MongoDBError, "Collection #{name} already exists. " +
|
275
|
+
"Currently in strict mode."
|
274
276
|
else
|
275
277
|
return Collection.new(name, self, opts)
|
276
278
|
end
|
@@ -286,16 +288,19 @@ module Mongo
|
|
286
288
|
|
287
289
|
# Get a collection by name.
|
288
290
|
#
|
289
|
-
# @param [String] name the collection name.
|
291
|
+
# @param [String, Symbol] name the collection name.
|
290
292
|
# @param [Hash] opts any valid options that can be passed to Collection#new.
|
291
293
|
#
|
292
|
-
# @raise [MongoDBError] if collection does not already exist and we're in
|
294
|
+
# @raise [MongoDBError] if collection does not already exist and we're in
|
295
|
+
# +strict+ mode.
|
293
296
|
#
|
294
297
|
# @return [Mongo::Collection]
|
295
298
|
def collection(name, opts={})
|
296
|
-
if strict? && !collection_names.include?(name)
|
297
|
-
raise Mongo::MongoDBError, "Collection #{name} doesn't exist.
|
299
|
+
if strict? && !collection_names.include?(name.to_s)
|
300
|
+
raise Mongo::MongoDBError, "Collection #{name} doesn't exist. " +
|
301
|
+
"Currently in strict mode."
|
298
302
|
else
|
303
|
+
opts = opts.dup
|
299
304
|
opts[:safe] = opts.fetch(:safe, @safe)
|
300
305
|
opts.merge!(:pk => @pk_factory) unless opts[:pk]
|
301
306
|
Collection.new(name, self, opts)
|
@@ -305,11 +310,11 @@ module Mongo
|
|
305
310
|
|
306
311
|
# Drop a collection by +name+.
|
307
312
|
#
|
308
|
-
# @param [String] name
|
313
|
+
# @param [String, Symbol] name
|
309
314
|
#
|
310
315
|
# @return [Boolean] +true+ on success or +false+ if the collection name doesn't exist.
|
311
316
|
def drop_collection(name)
|
312
|
-
return true unless collection_names.include?(name)
|
317
|
+
return true unless collection_names.include?(name.to_s)
|
313
318
|
|
314
319
|
ok?(command(:drop => name))
|
315
320
|
end
|
@@ -590,11 +595,16 @@ module Mongo
|
|
590
595
|
# @raise [MongoDBError] if the command fails or there's a problem with the validation
|
591
596
|
# data, or if the collection is invalid.
|
592
597
|
def validate_collection(name)
|
593
|
-
|
594
|
-
|
595
|
-
|
596
|
-
|
597
|
-
|
598
|
+
cmd = BSON::OrderedHash.new
|
599
|
+
cmd[:validate] = name
|
600
|
+
cmd[:full] = true
|
601
|
+
doc = command(cmd, :check_response => false)
|
602
|
+
if !ok?(doc)
|
603
|
+
raise MongoDBError, "Error with validate command: #{doc.inspect}"
|
604
|
+
end
|
605
|
+
if (doc.has_key?('valid') && !doc['valid']) || (doc['result'] =~ /\b(exception|corrupt)\b/i)
|
606
|
+
raise MongoDBError, "Error: invalid collection #{name}: #{doc.inspect}"
|
607
|
+
end
|
598
608
|
doc
|
599
609
|
end
|
600
610
|
|
data/lib/mongo/gridfs/grid.rb
CHANGED
@@ -65,7 +65,8 @@ module Mongo
|
|
65
65
|
#
|
66
66
|
# @return [Mongo::ObjectId] the file's id.
|
67
67
|
def put(data, opts={})
|
68
|
-
|
68
|
+
opts = opts.dup
|
69
|
+
filename = opts[:filename]
|
69
70
|
opts.merge!(default_grid_io_opts)
|
70
71
|
file = GridIO.new(@files, @chunks, filename, 'w', opts=opts)
|
71
72
|
file.write(data)
|
data/lib/mongo/gridfs/grid_io.rb
CHANGED
@@ -55,6 +55,7 @@ module Mongo
|
|
55
55
|
@chunks = chunks
|
56
56
|
@filename = filename
|
57
57
|
@mode = mode
|
58
|
+
opts = opts.dup
|
58
59
|
@query = opts.delete(:query) || {}
|
59
60
|
@query_opts = opts.delete(:query_opts) || {}
|
60
61
|
@fs_name = opts.delete(:fs_name) || Grid::DEFAULT_FS_NAME
|
@@ -207,43 +208,9 @@ module Mongo
|
|
207
208
|
elsif separator.is_a?(Integer)
|
208
209
|
read_length(separator)
|
209
210
|
elsif separator.length > 1
|
210
|
-
|
211
|
-
len = 0
|
212
|
-
match_idx = 0
|
213
|
-
match_num = separator.length - 1
|
214
|
-
to_match = separator[match_idx].chr
|
215
|
-
if length
|
216
|
-
matcher = lambda {|idx, num| idx < num && len < length }
|
217
|
-
else
|
218
|
-
matcher = lambda {|idx, num| idx < num}
|
219
|
-
end
|
220
|
-
while matcher.call(match_idx, match_num) && char = getc
|
221
|
-
result << char
|
222
|
-
len += 1
|
223
|
-
if char == to_match
|
224
|
-
while match_idx < match_num do
|
225
|
-
match_idx += 1
|
226
|
-
to_match = separator[match_idx].chr
|
227
|
-
char = getc
|
228
|
-
result << char
|
229
|
-
if char != to_match
|
230
|
-
match_idx = 0
|
231
|
-
to_match = separator[match_idx].chr
|
232
|
-
break
|
233
|
-
end
|
234
|
-
end
|
235
|
-
end
|
236
|
-
end
|
237
|
-
result
|
211
|
+
read_to_string(separator, length)
|
238
212
|
else
|
239
|
-
|
240
|
-
len = 0
|
241
|
-
while char = getc
|
242
|
-
result << char
|
243
|
-
len += 1
|
244
|
-
break if char == separator || (length ? len >= length : false)
|
245
|
-
end
|
246
|
-
result
|
213
|
+
read_to_character(separator, length)
|
247
214
|
end
|
248
215
|
end
|
249
216
|
|
@@ -284,8 +251,9 @@ module Mongo
|
|
284
251
|
# @return [Mongo::GridIO] self
|
285
252
|
def each
|
286
253
|
return read_all unless block_given?
|
287
|
-
while chunk = read(chunk_size)
|
254
|
+
while chunk = read(chunk_size)
|
288
255
|
yield chunk
|
256
|
+
break if chunk.empty?
|
289
257
|
end
|
290
258
|
self
|
291
259
|
end
|
@@ -316,21 +284,18 @@ module Mongo
|
|
316
284
|
chunk
|
317
285
|
end
|
318
286
|
|
319
|
-
def last_chunk_number
|
320
|
-
(@file_length / @chunk_size).to_i
|
321
|
-
end
|
322
|
-
|
323
287
|
# Read a file in its entirety.
|
324
288
|
def read_all
|
325
289
|
buf = ''
|
326
290
|
if @current_chunk
|
327
291
|
buf << @current_chunk['data'].to_s
|
328
|
-
while
|
329
|
-
|
330
|
-
@current_chunk
|
292
|
+
while buf.size < @file_length
|
293
|
+
@current_chunk = get_chunk(@current_chunk['n'] + 1)
|
294
|
+
break if @current_chunk.nil?
|
295
|
+
buf << @current_chunk['data'].to_s
|
331
296
|
end
|
297
|
+
@file_position = @file_length
|
332
298
|
end
|
333
|
-
@file_position = @file_length
|
334
299
|
buf
|
335
300
|
end
|
336
301
|
|
@@ -361,6 +326,48 @@ module Mongo
|
|
361
326
|
buf
|
362
327
|
end
|
363
328
|
|
329
|
+
def read_to_character(character="\n", length=nil)
|
330
|
+
result = ''
|
331
|
+
len = 0
|
332
|
+
while char = getc
|
333
|
+
result << char
|
334
|
+
len += 1
|
335
|
+
break if char == character || (length ? len >= length : false)
|
336
|
+
end
|
337
|
+
result.length > 0 ? result : nil
|
338
|
+
end
|
339
|
+
|
340
|
+
def read_to_string(string="\n", length=nil)
|
341
|
+
result = ''
|
342
|
+
len = 0
|
343
|
+
match_idx = 0
|
344
|
+
match_num = string.length - 1
|
345
|
+
to_match = string[match_idx].chr
|
346
|
+
if length
|
347
|
+
matcher = lambda {|idx, num| idx < num && len < length }
|
348
|
+
else
|
349
|
+
matcher = lambda {|idx, num| idx < num}
|
350
|
+
end
|
351
|
+
while matcher.call(match_idx, match_num) && char = getc
|
352
|
+
result << char
|
353
|
+
len += 1
|
354
|
+
if char == to_match
|
355
|
+
while match_idx < match_num do
|
356
|
+
match_idx += 1
|
357
|
+
to_match = string[match_idx].chr
|
358
|
+
char = getc
|
359
|
+
result << char
|
360
|
+
if char != to_match
|
361
|
+
match_idx = 0
|
362
|
+
to_match = string[match_idx].chr
|
363
|
+
break
|
364
|
+
end
|
365
|
+
end
|
366
|
+
end
|
367
|
+
end
|
368
|
+
result.length > 0 ? result : nil
|
369
|
+
end
|
370
|
+
|
364
371
|
def cache_chunk_data
|
365
372
|
@current_chunk_data = @current_chunk['data'].to_s
|
366
373
|
if @current_chunk_data.respond_to?(:force_encoding)
|
@@ -413,6 +420,7 @@ module Mongo
|
|
413
420
|
|
414
421
|
# Initialize the class for writing a file.
|
415
422
|
def init_write(opts)
|
423
|
+
opts = opts.dup
|
416
424
|
@files_id = opts.delete(:_id) || BSON::ObjectId.new
|
417
425
|
@content_type = opts.delete(:content_type) || (defined? MIME) && get_content_type || DEFAULT_CONTENT_TYPE
|
418
426
|
@chunk_size = opts.delete(:chunk_size) || DEFAULT_CHUNK_SIZE
|
@@ -455,7 +463,9 @@ module Mongo
|
|
455
463
|
@server_md5 = @files.db.command(md5_command)['md5']
|
456
464
|
if @safe
|
457
465
|
@client_md5 = @local_md5.hexdigest
|
458
|
-
if @local_md5
|
466
|
+
if @local_md5 == @server_md5
|
467
|
+
@server_md5
|
468
|
+
else
|
459
469
|
raise GridMD5Failure, "File on server failed MD5 check"
|
460
470
|
end
|
461
471
|
else
|