diff --git a/lib/mongo/gridfs/grid_io.rb b/lib/mongo/gridfs/grid_io.rb index 982e238..7449ef4 100644 --- a/lib/mongo/gridfs/grid_io.rb +++ b/lib/mongo/gridfs/grid_io.rb @@ -32,7 +32,7 @@ module Mongo PROTECTED_ATTRS = [:files_id, :file_length, :client_md5, :server_md5] attr_reader :content_type, :chunk_size, :upload_date, :files_id, :filename, - :metadata, :server_md5, :client_md5, :file_length + :metadata, :server_md5, :client_md5, :file_length, :file_position # Create a new GridIO object. Note that most users will not need to use this class directly; # the Grid and GridFileSystem classes will instantiate this class @@ -242,11 +242,14 @@ module Mongo # Read a file in its entirety. def read_all buf = '' - while true + if @current_chunk buf << @current_chunk['data'].to_s - @current_chunk = get_chunk(@current_chunk['n'] + 1) - break unless @current_chunk + while chunk = get_chunk(@current_chunk['n'] + 1) + buf << chunk['data'].to_s + @current_chunk = chunk + end end + @file_position = @file_length buf end @@ -254,7 +257,11 @@ module Mongo def read_length(length) cache_chunk_data remaining = (@file_length - @file_position) - to_read = length > remaining ? remaining : length + if length.nil? + to_read = remaining + else + to_read = length > remaining ? remaining : length + end return nil unless remaining > 0 buf = '' diff --git a/test/grid_file_system_test.rb b/test/grid_file_system_test.rb index 5504617..615bd4e 100644 --- a/test/grid_file_system_test.rb +++ b/test/grid_file_system_test.rb @@ -9,8 +9,8 @@ class GridFileSystemTest < Test::Unit::TestCase end teardown do - @db['fs.files'].remove - @db['fs.chunks'].remove + @db.drop_collection('fs.files') + @db.drop_collection('fs.chunks') end context "When reading:" do diff --git a/test/grid_io_test.rb b/test/grid_io_test.rb index 4226159..ed59b74 100644 --- a/test/grid_io_test.rb +++ b/test/grid_io_test.rb @@ -33,6 +33,39 @@ class GridIOTest < Test::Unit::TestCase end end + context "Seeking" do + setup do + @filename = 'test' + @mode = 'w' + @data = "1" * 1024 * 1024 + @file = GridIO.new(@files, @chunks, @filename, @mode) + @file.write(@data) + @file.close + end + + should "read all data using read_length and then be able to seek" do + file = GridIO.new(@files, @chunks, nil, "r", :query => {:_id => @file.files_id}) + assert_equal @data, file.read(1024 * 1024) + file.seek(0) + assert_equal @data, file.read + end + + should "read all data using read_all and then be able to seek" do + file = GridIO.new(@files, @chunks, nil, "r", :query => {:_id => @file.files_id}) + assert_equal @data, file.read + file.seek(0) + assert_equal @data, file.read + file.seek(1024 * 512) + assert_equal 524288, file.file_position + assert_equal @data.length / 2, file.read.length + assert_equal 1048576, file.file_position + assert_nil file.read + file.seek(1024 * 512) + assert_equal 524288, file.file_position + end + + end + context "Grid MD5 check" do should "run in safe mode" do file = GridIO.new(@files, @chunks, 'smallfile', 'w', :safe => true)