# See http://doc.gitlab.com/ce/development/migration_style_guide.html # for more information on how to write migrations for GitLab. class MovePersonalSnippetsFiles < ActiveRecord::Migration[4.2] include Gitlab::Database::MigrationHelpers disable_ddl_transaction! DOWNTIME = false def up return unless file_storage? @source_relative_location = File.join('/uploads', 'personal_snippet') @destination_relative_location = File.join('/uploads', '-', 'system', 'personal_snippet') move_personal_snippet_files end def down return unless file_storage? @source_relative_location = File.join('/uploads', '-', 'system', 'personal_snippet') @destination_relative_location = File.join('/uploads', 'personal_snippet') move_personal_snippet_files end def move_personal_snippet_files query = "SELECT uploads.path, uploads.model_id, snippets.description FROM uploads "\ "INNER JOIN snippets ON snippets.id = uploads.model_id WHERE uploader = 'PersonalFileUploader'" select_all(query).each do |upload| secret = upload['path'].split('/')[0] file_name = upload['path'].split('/')[1] next unless move_file(upload['model_id'], secret, file_name) update_markdown(upload['model_id'], secret, file_name, upload['description']) end end def move_file(snippet_id, secret, file_name) source_dir = File.join(base_directory, @source_relative_location, snippet_id.to_s, secret) destination_dir = File.join(base_directory, @destination_relative_location, snippet_id.to_s, secret) source_file_path = File.join(source_dir, file_name) destination_file_path = File.join(destination_dir, file_name) unless File.exist?(source_file_path) say "Source file `#{source_file_path}` doesn't exist. Skipping." return end say "Moving file #{source_file_path} -> #{destination_file_path}" FileUtils.mkdir_p(destination_dir) FileUtils.move(source_file_path, destination_file_path) true end def update_markdown(snippet_id, secret, file_name, description) source_markdown_path = File.join(@source_relative_location, snippet_id.to_s, secret, file_name) destination_markdown_path = File.join(@destination_relative_location, snippet_id.to_s, secret, file_name) source_markdown = "](#{source_markdown_path})" destination_markdown = "](#{destination_markdown_path})" if description.present? description = description.gsub(source_markdown, destination_markdown) quoted_description = quote_string(description) execute("UPDATE snippets SET description = '#{quoted_description}', description_html = NULL "\ "WHERE id = #{snippet_id}") end query = "SELECT id, note FROM notes WHERE noteable_id = #{snippet_id} "\ "AND noteable_type = 'Snippet' AND note IS NOT NULL" select_all(query).each do |note| text = note['note'].gsub(source_markdown, destination_markdown) quoted_text = quote_string(text) execute("UPDATE notes SET note = '#{quoted_text}', note_html = NULL WHERE id = #{note['id']}") end end def base_directory File.join(Rails.root, 'public') end def file_storage? CarrierWave::Uploader::Base.storage == CarrierWave::Storage::File end end