From 2e1c431ad2c1051666c19af4913e76d11c75ae9d Mon Sep 17 00:00:00 2001 From: Brandon Dunne Date: Thu, 11 Jan 2018 16:24:21 -0500 Subject: [PATCH] Migrate Picture content from BinaryBlobs to Pictures table https://bugzilla.redhat.com/show_bug.cgi?id=1532286 --- ...1162442_move_pictures_blobs_to_pictures.rb | 51 +++++++++ ...42_move_pictures_blobs_to_pictures_spec.rb | 106 ++++++++++++++++++ 2 files changed, 157 insertions(+) create mode 100644 db/migrate/20180111162442_move_pictures_blobs_to_pictures.rb create mode 100644 spec/migrations/20180111162442_move_pictures_blobs_to_pictures_spec.rb diff --git a/db/migrate/20180111162442_move_pictures_blobs_to_pictures.rb b/db/migrate/20180111162442_move_pictures_blobs_to_pictures.rb new file mode 100644 index 000000000..f13586f4c --- /dev/null +++ b/db/migrate/20180111162442_move_pictures_blobs_to_pictures.rb @@ -0,0 +1,51 @@ +class MovePicturesBlobsToPictures < ActiveRecord::Migration[5.0] + class BinaryBlob < ActiveRecord::Base + has_many :binary_blob_parts, -> { order(:id) }, :dependent => :delete_all + belongs_to :resource, :polymorphic => true + def data + binary_blob_parts.pluck(:data).join + end + end + class BinaryBlobPart < ActiveRecord::Base; end + class Picture < ActiveRecord::Base + include ActiveRecord::IdRegions + end + + def up + add_column :pictures, :content, :binary + add_column :pictures, :extension, :string + add_column :pictures, :md5, :string + + say_with_time("Moving picture content from BinaryBlobs to the pictures table") do + BinaryBlob.where(:resource_type => "Picture").all.each do |blob| + Picture.update(blob.resource_id, :content => blob.data, :extension => blob.data_type, :md5 => blob.md5) + blob.destroy + end + end + end + + def down + say_with_time("Moving picture content from the pictures table to BinaryBlobs") do + Picture.in_my_region.all.each do |picture| + size = picture.content.try(:length).to_i + + BinaryBlob.create!( + :data_type => picture.extension, + :md5 => picture.md5, + :part_size => size, + :resource_id => picture.id, + :resource_type => "Picture", + :size => size, + ).binary_blob_parts.create!( + :data => picture.content, + :md5 => picture.md5, + :size => size, + ) + end + end + + remove_column :pictures, :content + remove_column :pictures, :extension + remove_column :pictures, :md5 + end +end diff --git a/spec/migrations/20180111162442_move_pictures_blobs_to_pictures_spec.rb b/spec/migrations/20180111162442_move_pictures_blobs_to_pictures_spec.rb new file mode 100644 index 000000000..88fbfc091 --- /dev/null +++ b/spec/migrations/20180111162442_move_pictures_blobs_to_pictures_spec.rb @@ -0,0 +1,106 @@ +require_migration + +describe MovePicturesBlobsToPictures do + let(:binary_blob_stub) { migration_stub :BinaryBlob } + let(:binary_blob_part_stub) { migration_stub :BinaryBlobPart } + let(:picture_stub) { migration_stub :Picture } + + migration_context :up do + it 'Moves a single-part image blob' do + picture = picture_stub.create! + blob = binary_blob_stub.create!( + :data_type => "png", + :md5 => "ce114e4501d2f4e2dcea3e17b546f339", + :part_size => 1.megabyte, + :resource_id => picture.id, + :resource_type => "Picture", + :size => 14, + ) + binary_blob_part_stub.create!( + :binary_blob_id => blob.id, + :data => "This is a test", + :md5 => "ce114e4501d2f4e2dcea3e17b546f339", + :size => 14, + ) + + migrate + + expect(picture.reload).to have_attributes( + :content => "This is a test", + :extension => "png", + :md5 => "ce114e4501d2f4e2dcea3e17b546f339", + ) + expect(binary_blob_stub.count).to eq(0) + expect(binary_blob_part_stub.count).to eq(0) + end + + it 'Moves a multi-part image blob' do + picture = picture_stub.create! + blob = binary_blob_stub.create!( + :data_type => "png", + :md5 => "c65dfd70c813cc2d519fcad28ebaee6f", + :part_size => 1.megabyte, + :resource_id => picture.id, + :resource_type => "Picture", + :size => 32, + ) + binary_blob_part_stub.create!( + :binary_blob_id => blob.id, + :data => "This is a multi", + :md5 => "94efec8abb26d346812c3a0a8dc98306", + :size => 15, + ) + binary_blob_part_stub.create!( + :binary_blob_id => blob.id, + :data => "-part test stri", + :md5 => "10b11598b01f3b02d767e238be22e78b", + :size => 15, + ) + binary_blob_part_stub.create!( + :binary_blob_id => blob.id, + :data => "ng", + :md5 => "66e10e9ff65ef479654dde3968d3440d", + :size => 2, + ) + + migrate + + expect(picture.reload).to have_attributes( + :content => "This is a multi-part test string", + :extension => "png", + :md5 => "c65dfd70c813cc2d519fcad28ebaee6f", + ) + expect(binary_blob_stub.count).to eq(0) + expect(binary_blob_part_stub.count).to eq(0) + end + end + + migration_context :down do + it 'Moves back to a single binary blob' do + picture = picture_stub.create!( + :content => "This is a test", + :extension => "png", + :md5 => "ce114e4501d2f4e2dcea3e17b546f339", + ) + + migrate + + expect(binary_blob_stub.count).to eq(1) + expect(binary_blob_part_stub.count).to eq(1) + expect(binary_blob_stub.first).to have_attributes( + :data_type => "png", + :md5 => "ce114e4501d2f4e2dcea3e17b546f339", + :part_size => 14, + :resource_id => picture.id, + :resource_type => "Picture", + :size => 14, + ) + expect(binary_blob_part_stub.first).to have_attributes( + :binary_blob_id => binary_blob_stub.first.id, + :data => "This is a test", + :md5 => "ce114e4501d2f4e2dcea3e17b546f339", + :size => 14, + ) + end + end +end