diff --git a/lib/mongo/gridfs/grid_store.rb b/lib/mongo/gridfs/grid_store.rb index 3035c1e..969e043 100644 --- a/lib/mongo/gridfs/grid_store.rb +++ b/lib/mongo/gridfs/grid_store.rb @@ -28,6 +28,9 @@ module XGen # } class GridStore + DEFAULT_ROOT_COLLECTION = 'gridfs' + DEFAULT_CONTENT_TYPE = 'text/plain' + include Enumerable attr_accessor :filename @@ -35,10 +38,13 @@ module XGen # Array of strings; may be +nil+ attr_accessor :aliases - # Default is 'text/plain' + # Default is DEFAULT_CONTENT_TYPE attr_accessor :content_type - attr_reader :object_id, :upload_date + attr_reader :object_id + + # Time that the file was first saved. + attr_reader :upload_date attr_reader :chunk_size @@ -50,8 +56,8 @@ module XGen db.collection('_files').find({'filename' => name}).next_object.nil? end - def open(db, name, mode) - gs = self.new(db, name, mode) + def open(db, name, mode, options={}) + gs = self.new(db, name, mode, options) result = nil begin result = yield gs if block_given? @@ -90,7 +96,17 @@ module XGen #+++ # Mode may only be 'r', 'w', or 'w+'. - def initialize(db, name, mode='r') + # + # Options: + # + # :chunk_size :: Ignored if mode is 'r' or 'w+'. Sets chunk size for + # files opened for writing ('w'). See also #chunk_size= + # which may only be called before any data is written. + # + # :content_type :: Ignored if mode is 'r' or 'w+'. String. Default + # value is DEFAULT_CONTENT_TYPE. See also + # #content_type= + def initialize(db, name, mode='r', options={}) @db, @filename, @mode = db, name, mode doc = @db.collection('_files').find({'filename' => @filename}).next_object @@ -112,7 +128,7 @@ module XGen else @upload_date = Time.new @chunk_size = Chunk::DEFAULT_CHUNK_SIZE - @content_type = 'text/plain' + @content_type = DEFAULT_CONTENT_TYPE @length = 0 end @@ -122,6 +138,8 @@ module XGen when 'w' delete_chunks @first_chunk = @curr_chunk = nil + @content_type = options[:content_type] if options[:content_type] + @chunk_size = options[:chunk_size] if options[:chunk_size] when 'w+' @curr_chunk = find_last_chunk @curr_chunk.pos = @curr_chunk.data.length if @curr_chunk @@ -340,6 +358,7 @@ module XGen files.remove('_id' => @object_id) else @object_id = XGen::Mongo::Driver::ObjectID.new + @upload_date = Time.now end files.insert(to_mongo_object) end diff --git a/tests/test_grid_store.rb b/tests/test_grid_store.rb index 5f19cc9..366e60c 100644 --- a/tests/test_grid_store.rb +++ b/tests/test_grid_store.rb @@ -174,4 +174,43 @@ class GridStoreTest < Test::Unit::TestCase } end + def test_chunk_size_in_option + GridStore.open(@db, 'new-file', 'w', :chunk_size => 42) { |f| f.write("foo") } + GridStore.open(@db, 'new-file', 'r') { |f| + assert f.chunk_size == 42 + } + end + + def test_upload_date + now = Time.now + orig_file_upload_date = nil + GridStore.open(@db, 'foobar', 'r') { |f| orig_file_upload_date = f.upload_date } + assert_not_nil orig_file_upload_date + assert (orig_file_upload_date - now) < 5 # even a really slow system < 5 secs + + sleep(2) + GridStore.open(@db, 'foobar', 'w') { |f| f.write "new data" } + file_upload_date = nil + GridStore.open(@db, 'foobar', 'r') { |f| file_upload_date = f.upload_date } + assert_equal orig_file_upload_date, file_upload_date + end + + def test_content_type + ct = nil + GridStore.open(@db, 'foobar', 'r') { |f| ct = f.content_type } + assert_equal GridStore::DEFAULT_CONTENT_TYPE, ct + + GridStore.open(@db, 'foobar', 'w+') { |f| f.content_type = 'text/html' } + ct2 = nil + GridStore.open(@db, 'foobar', 'r') { |f| ct2 = f.content_type } + assert_equal 'text/html', ct2 + end + + def test_content_type_option + GridStore.open(@db, 'new-file', 'w', :content_type => 'image/jpg') { |f| f.write('foo') } + ct = nil + GridStore.open(@db, 'new-file', 'r') { |f| ct = f.content_type } + assert_equal 'image/jpg', ct + end + end