options to delete old versions of GridFileSystem files
This commit is contained in:
parent
c276a23615
commit
85fd06f990
|
@ -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']})
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue