Commit c156030e authored by Bob Van Landuyt's avatar Bob Van Landuyt

Add a background migration to rename `uploads` in the uploads table

parent 79f591df
class EnqueueMigrateSystemUploadsToNewFolder < ActiveRecord::Migration
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
OLD_FOLDER = 'uploads/system/'
NEW_FOLDER = 'uploads/-/system/'
disable_ddl_transaction!
def up
BackgroundMigrationWorker.perform_async('MigrateSystemUploadsToNewFolder',
[OLD_FOLDER, NEW_FOLDER])
end
def down
BackgroundMigrationWorker.perform_async('MigrateSystemUploadsToNewFolder',
[NEW_FOLDER, OLD_FOLDER])
end
end
......@@ -11,7 +11,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20170717111152) do
ActiveRecord::Schema.define(version: 20170717150329) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
......
module Gitlab
module BackgroundMigration
class MigrateSystemUploadsToNewFolder
include Gitlab::Database::MigrationHelpers
attr_reader :old_folder, :new_folder
def perform(old_folder, new_folder)
@old_folder = old_folder
@new_folder = new_folder
replace_sql = replace_sql(uploads[:path], old_folder, new_folder)
while remaining_rows > 0
sql = "UPDATE uploads "\
"SET path = #{replace_sql} "\
"WHERE uploads.id IN "\
" (SELECT uploads.id FROM uploads "\
" WHERE #{affected_uploads.to_sql} LIMIT 1000)"
connection.execute(sql)
end
end
def uploads
Arel::Table.new('uploads')
end
def remaining_rows
remaining_result = connection.exec_query("SELECT count(id) FROM uploads WHERE #{affected_uploads.to_sql}")
remaining = remaining_result.first['count'].to_i
logger.info "#{remaining} uploads remaining"
remaining
end
def affected_uploads
uploads[:path].matches("#{old_folder}%")
end
def connection
ActiveRecord::Base.connection
end
def logger
Sidekiq.logger || Rails.logger || Logger.new(STDOUT)
end
end
end
end
require 'spec_helper'
describe Gitlab::BackgroundMigration::MigrateSystemUploadsToNewFolder do
let(:migration) { described_class.new }
before do
allow(migration).to receive(:logger).and_return(Logger.new(nil))
end
describe '#perform' do
it 'renames the path of system-uploads', truncate: true do
upload = create(:upload, model: create(:empty_project), path: 'uploads/system/project/avatar.jpg')
migration.perform('uploads/system/', 'uploads/-/system/')
expect(upload.reload.path).to eq('uploads/-/system/project/avatar.jpg')
end
end
end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment