options to delete old versions of GridFileSystem files

This commit is contained in:
Kyle Banker 2010-03-30 13:22:22 -04:00
parent c276a23615
commit 85fd06f990
3 changed files with 37 additions and 9 deletions

View File

@ -53,6 +53,8 @@ module Mongo
# the content type will may be inferred from the filename extension if the mime-types gem can be # the content type will may be inferred from the filename extension if the mime-types gem can be
# loaded. Otherwise, the content type 'binary/octet-stream' will be used. # loaded. Otherwise, the content type 'binary/octet-stream' will be used.
# @options opts [Integer] (262144) :chunk_size size of file chunks in bytes. # @options opts [Integer] (262144) :chunk_size size of file chunks in bytes.
# @options opts [Boolean] :delete_old (false) ensure that old versions of the file are deleted. This option
# only work in 'w' mode.
# @options opts [Boolean] :safe (false) When safe mode is enabled, the chunks sent to the server # @options opts [Boolean] :safe (false) When safe mode is enabled, the chunks sent to the server
# will be validated using an md5 hash. If validation fails, an exception will be raised. # will be validated using an md5 hash. If validation fails, an exception will be raised.
# #
@ -76,15 +78,23 @@ module Mongo
# @grid.open('image.jpg, 'w') do |f| # @grid.open('image.jpg, 'w') do |f|
# f.write @file # f.write @file
# end # end
#
# @return [Mongo::GridIO]
def open(filename, mode, opts={}) def open(filename, mode, opts={})
opts.merge!(default_grid_io_opts(filename)) opts.merge!(default_grid_io_opts(filename))
del = opts.delete(:delete_old) && mode == 'w'
file = GridIO.new(@files, @chunks, filename, mode, opts) file = GridIO.new(@files, @chunks, filename, mode, opts)
return file unless block_given? return file unless block_given?
result = nil result = nil
begin begin
result = yield file result = yield file
ensure ensure
file.close id = file.close
if del
self.delete do
@files.find({'filename' => filename, '_id' => {'$ne' => id}}, :fields => ['_id'])
end
end
end end
result result
end end
@ -94,9 +104,15 @@ module Mongo
# #
# @param [String] filename # @param [String] filename
# #
# @yield [] pass a block that returns an array of documents to be deleted.
#
# @return [Boolean] # @return [Boolean]
def delete(filename) def delete(filename=nil)
if block_given?
files = yield
else
files = @files.find({'filename' => filename}, :fields => ['_id']) files = @files.find({'filename' => filename}, :fields => ['_id'])
end
files.each do |file| files.each do |file|
@files.remove({'_id' => file['_id']}) @files.remove({'_id' => file['_id']})
@chunks.remove({'files_id' => file['_id']}) @chunks.remove({'files_id' => file['_id']})

View File

@ -163,16 +163,16 @@ module Mongo
# This method will be invoked automatically when # This method will be invoked automatically when
# on GridIO#open is passed a block. Otherwise, it must be called manually. # on GridIO#open is passed a block. Otherwise, it must be called manually.
# #
# @return [True] # @return [Mongo::ObjectID]
def close def close
if @mode[0] == ?w if @mode[0] == ?w
if @current_chunk['n'].zero? && @chunk_position.zero? if @current_chunk['n'].zero? && @chunk_position.zero?
warn "Warning: Storing a file with zero length." warn "Warning: Storing a file with zero length."
end end
@upload_date = Time.now.utc @upload_date = Time.now.utc
@files.insert(to_mongo_object) id = @files.insert(to_mongo_object)
end end
true id
end end
def inspect def inspect

View File

@ -109,9 +109,9 @@ class GridFileSystemTest < Test::Unit::TestCase
context "and on a second overwrite" do context "and on a second overwrite" do
setup do setup do
sleep(2) sleep(2)
new_data = "NEW" * 1000 @new_data = "NEW" * 1000
@grid.open('sample', 'w') do |f| @grid.open('sample', 'w') do |f|
f.write new_data f.write @new_data
end end
@ids = @db['fs.files'].find({'filename' => 'sample'}).map {|file| file['_id']} @ids = @db['fs.files'].find({'filename' => 'sample'}).map {|file| file['_id']}
@ -127,6 +127,18 @@ class GridFileSystemTest < Test::Unit::TestCase
assert_equal 0, @db['fs.files'].find({'filename' => 'sample'}).count assert_equal 0, @db['fs.files'].find({'filename' => 'sample'}).count
assert_equal 0, @db['fs.chunks'].find({'files_id' => {'$in' => @ids}}).count assert_equal 0, @db['fs.chunks'].find({'files_id' => {'$in' => @ids}}).count
end end
should "delete old versions on write with :delete_old is passed in" do
@grid.open('sample', 'w', :delete_old => true) do |f|
f.write @new_data
end
@new_ids = @db['fs.files'].find({'filename' => 'sample'}).map {|file| file['_id']}
assert_equal 1, @new_ids.length
id = @new_ids.first
assert !@ids.include?(id)
assert_equal 1, @db['fs.files'].find({'filename' => 'sample'}).count
assert_equal 1, @db['fs.chunks'].find({'files_id' => id}).count
end
end end
end end
end end