summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBob Van Landuyt <bob@vanlanduyt.co>2017-07-17 15:23:59 +0200
committerBob Van Landuyt <bob@vanlanduyt.co>2017-07-18 15:38:54 +0200
commitc156030ef965bed019def3993ee21d214fe2f2ba (patch)
tree2923a0a90a73ce6509f40397874f7a4483e0393e
parent79f591df4dfd6577c55d3bb843e423bba859e9b9 (diff)
downloadgitlab-ce-c156030ef965bed019def3993ee21d214fe2f2ba.tar.gz
Add a background migration to rename `uploads` in the uploads table
-rw-r--r--db/post_migrate/20170717150329_enqueue_migrate_system_uploads_to_new_folder.rb20
-rw-r--r--db/schema.rb2
-rw-r--r--lib/gitlab/background_migration/migrate_system_uploads_to_new_folder.rb47
-rw-r--r--spec/lib/gitlab/background_migration/migrate_system_uploads_to_new_folder_spec.rb19
4 files changed, 87 insertions, 1 deletions
diff --git a/db/post_migrate/20170717150329_enqueue_migrate_system_uploads_to_new_folder.rb b/db/post_migrate/20170717150329_enqueue_migrate_system_uploads_to_new_folder.rb
new file mode 100644
index 00000000000..87069dce006
--- /dev/null
+++ b/db/post_migrate/20170717150329_enqueue_migrate_system_uploads_to_new_folder.rb
@@ -0,0 +1,20 @@
+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
diff --git a/db/schema.rb b/db/schema.rb
index 0195d73db39..284b2068166 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -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"
diff --git a/lib/gitlab/background_migration/migrate_system_uploads_to_new_folder.rb b/lib/gitlab/background_migration/migrate_system_uploads_to_new_folder.rb
new file mode 100644
index 00000000000..601c874bc9b
--- /dev/null
+++ b/lib/gitlab/background_migration/migrate_system_uploads_to_new_folder.rb
@@ -0,0 +1,47 @@
+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
diff --git a/spec/lib/gitlab/background_migration/migrate_system_uploads_to_new_folder_spec.rb b/spec/lib/gitlab/background_migration/migrate_system_uploads_to_new_folder_spec.rb
new file mode 100644
index 00000000000..a910fb105a5
--- /dev/null
+++ b/spec/lib/gitlab/background_migration/migrate_system_uploads_to_new_folder_spec.rb
@@ -0,0 +1,19 @@
+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