Project

General

Profile

Patch #25215 » 0001-reuse-existing-identical-disk-files-for-new-attachme.patch

patch against current trunk - Jens Krämer, 2017-02-28 04:08

View differences:

app/models/attachment.rb
56 56
  before_create :files_to_final_location
57 57
  after_rollback :delete_from_disk, :on => :create
58 58
  after_commit :delete_from_disk, :on => :destroy
59
  after_commit :reuse_existing_file_if_possible, :on => :create
59 60

  
60 61
  safe_attributes 'filename', 'content_type', 'description'
61 62

  
......
387 388

  
388 389
  private
389 390

  
391
  def reuse_existing_file_if_possible
392
    with_lock do
393
      if existing = Attachment
394
                      .lock
395
                      .where(digest: self.digest, filesize: self.filesize)
396
                      .where('id <> ? and disk_filename <> ?',
397
                             self.id, self.disk_filename)
398
                      .first
399

  
400
        original_diskfile = self.diskfile
401
        self.update_columns disk_directory: existing.disk_directory,
402
                            disk_filename: existing.disk_filename
403
        File.delete(original_diskfile) if File.exist?(original_diskfile)
404
      end
405
    end
406
  end
407

  
408

  
390 409
  # Physically deletes the file from the file system
391 410
  def delete_from_disk!
392 411
    if disk_filename.present? && File.exist?(diskfile)
test/unit/attachment_test.rb
94 94
  end
95 95

  
96 96
  def test_copy_should_preserve_attributes
97

  
98
    # prevent re-use of data from other attachments with equal contents
99
    Attachment.where('id <> 1').destroy_all
100

  
97 101
    a = Attachment.find(1)
98 102
    copy = a.copy
99 103

  
......
220 224
    assert_equal 'text/plain', a.content_type
221 225
  end
222 226

  
223
  def test_identical_attachments_at_the_same_time_should_not_overwrite
227
  def test_identical_attachments_should_reuse_same_file
224 228
    a1 = Attachment.create!(:container => Issue.find(1),
225 229
                            :file => uploaded_test_file("testfile.txt", ""),
226 230
                            :author => User.find(1))
227 231
    a2 = Attachment.create!(:container => Issue.find(1),
228 232
                            :file => uploaded_test_file("testfile.txt", ""),
229 233
                            :author => User.find(1))
230
    assert a1.disk_filename != a2.disk_filename
234
    assert_equal a1.diskfile, a2.diskfile
231 235
  end
232 236

  
233 237
  def test_filename_should_be_basenamed
(1-1/2)