diff options
author | Grzegorz Bizon <grzesiek.bizon@gmail.com> | 2017-05-03 12:27:30 +0200 |
---|---|---|
committer | Grzegorz Bizon <grzesiek.bizon@gmail.com> | 2017-05-03 12:27:30 +0200 |
commit | 738bf2c23891467dbc9c74d08223fd3c4e432ae7 (patch) | |
tree | 46f3aecaa33309822710a3aac2bb211a4855b37b /lib/gitlab/database/rename_reserved_paths_migration/v1/rename_base.rb | |
parent | eb45582f55cae42acc41fa228f4797b4067c01dc (diff) | |
parent | 40cc917a9c07263db062c03f62c8056ed40197bd (diff) | |
download | gitlab-ce-738bf2c23891467dbc9c74d08223fd3c4e432ae7.tar.gz |
Merge branch 'master' into feature/gb/manual-actions-protected-branches-permissions
* master: (103 commits)
Include missing project attributes to Import/Export
Create the rest of the wiki docs
Fill in information about creating the wiki Home page
Move wiki doc to its own index page
Create initial file for Wiki documentation
Default to null user when asignee is unselected
Re-enable ref operations with gitaly after not-found fix
#31560 Add repo parameter to gitaly:install and workhorse:install
Remove N+1 queries when checking nodes visible to user
Don't validate reserved words if the format doesn't match
Revert "Shorten and improve some job names"
Remove unused initializer
DRY the `<<: *except-docs` a bit in `.gitlab-ci.yml`
Make the static-analysis job be run for docs branches too
Add download_snippet_path helper
Refresh the markdown cache if it was `nil`
Add some documentation for the new migration helpers
Update comments
Display comments for personal snippets
Update docs on creating a project
...
Diffstat (limited to 'lib/gitlab/database/rename_reserved_paths_migration/v1/rename_base.rb')
-rw-r--r-- | lib/gitlab/database/rename_reserved_paths_migration/v1/rename_base.rb | 131 |
1 files changed, 131 insertions, 0 deletions
diff --git a/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_base.rb b/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_base.rb new file mode 100644 index 00000000000..de4e6e7c404 --- /dev/null +++ b/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_base.rb @@ -0,0 +1,131 @@ +module Gitlab + module Database + module RenameReservedPathsMigration + module V1 + class RenameBase + attr_reader :paths, :migration + + delegate :update_column_in_batches, + :replace_sql, + to: :migration + + def initialize(paths, migration) + @paths = paths + @migration = migration + end + + def path_patterns + @path_patterns ||= paths.map { |path| "%#{path}" } + end + + def rename_path_for_routable(routable) + old_path = routable.path + old_full_path = routable.full_path + # Only remove the last occurrence of the path name to get the parent namespace path + namespace_path = remove_last_occurrence(old_full_path, old_path) + new_path = rename_path(namespace_path, old_path) + new_full_path = join_routable_path(namespace_path, new_path) + + # skips callbacks & validations + routable.class.where(id: routable). + update_all(path: new_path) + + rename_routes(old_full_path, new_full_path) + + [old_full_path, new_full_path] + end + + def rename_routes(old_full_path, new_full_path) + replace_statement = replace_sql(Route.arel_table[:path], + old_full_path, + new_full_path) + + update_column_in_batches(:routes, :path, replace_statement) do |table, query| + query.where(MigrationClasses::Route.arel_table[:path].matches("#{old_full_path}%")) + end + end + + def rename_path(namespace_path, path_was) + counter = 0 + path = "#{path_was}#{counter}" + + while route_exists?(join_routable_path(namespace_path, path)) + counter += 1 + path = "#{path_was}#{counter}" + end + + path + end + + def remove_last_occurrence(string, pattern) + string.reverse.sub(pattern.reverse, "").reverse + end + + def join_routable_path(namespace_path, top_level) + if namespace_path.present? + File.join(namespace_path, top_level) + else + top_level + end + end + + def route_exists?(full_path) + MigrationClasses::Route.where(Route.arel_table[:path].matches(full_path)).any? + end + + def move_pages(old_path, new_path) + move_folders(pages_dir, old_path, new_path) + end + + def move_uploads(old_path, new_path) + return unless file_storage? + + move_folders(uploads_dir, old_path, new_path) + end + + def move_folders(directory, old_relative_path, new_relative_path) + old_path = File.join(directory, old_relative_path) + return unless File.directory?(old_path) + + new_path = File.join(directory, new_relative_path) + FileUtils.mv(old_path, new_path) + end + + def remove_cached_html_for_projects(project_ids) + update_column_in_batches(:projects, :description_html, nil) do |table, query| + query.where(table[:id].in(project_ids)) + end + + update_column_in_batches(:issues, :description_html, nil) do |table, query| + query.where(table[:project_id].in(project_ids)) + end + + update_column_in_batches(:merge_requests, :description_html, nil) do |table, query| + query.where(table[:target_project_id].in(project_ids)) + end + + update_column_in_batches(:notes, :note_html, nil) do |table, query| + query.where(table[:project_id].in(project_ids)) + end + + update_column_in_batches(:milestones, :description_html, nil) do |table, query| + query.where(table[:project_id].in(project_ids)) + end + end + + def file_storage? + CarrierWave::Uploader::Base.storage == CarrierWave::Storage::File + end + + def uploads_dir + File.join(CarrierWave.root, "uploads") + end + + def pages_dir + Settings.pages.path + end + end + end + end + end +end |