Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDouwe Maan <douwe@gitlab.com>2015-04-21 13:00:32 +0300
committerDouwe Maan <douwe@gitlab.com>2015-04-24 15:49:23 +0300
commit4934bc031205c668d4405c2a6faaee32367234d6 (patch)
treed21a9c12fc332d27e37b80a46328f415433982e3 /db/migrate/20150421120000_remove_periods_at_ends_of_usernames.rb
parentfac1f83fd51d4d6cc6e8a0c571507bca4460b514 (diff)
Change migration timestamp.
Diffstat (limited to 'db/migrate/20150421120000_remove_periods_at_ends_of_usernames.rb')
-rw-r--r--db/migrate/20150421120000_remove_periods_at_ends_of_usernames.rb80
1 files changed, 80 insertions, 0 deletions
diff --git a/db/migrate/20150421120000_remove_periods_at_ends_of_usernames.rb b/db/migrate/20150421120000_remove_periods_at_ends_of_usernames.rb
new file mode 100644
index 00000000000..e2f231ba709
--- /dev/null
+++ b/db/migrate/20150421120000_remove_periods_at_ends_of_usernames.rb
@@ -0,0 +1,80 @@
+class RemovePeriodsAtEndsOfUsernames < ActiveRecord::Migration
+ include Gitlab::ShellAdapter
+
+ class Namespace < ActiveRecord::Base
+ class << self
+ def find_by_path_or_name(path)
+ find_by("lower(path) = :path OR lower(name) = :path", path: path.downcase)
+ end
+
+ def clean_path(path)
+ path = path.dup
+ path.gsub!(/@.*\z/, "")
+ path.gsub!(/\.git\z/, "")
+ path.gsub!(/\A-+/, "")
+ path.gsub!(/\.+\z/, "")
+ path.gsub!(/[^a-zA-Z0-9_\-\.]/, "")
+
+ # Users with the great usernames of "." or ".." would end up with a blank username.
+ # Work around that by setting their username to "blank", followed by a counter.
+ path = "blank" if path.blank?
+
+ counter = 0
+ base = path
+ while Namespace.find_by_path_or_name(path)
+ counter += 1
+ path = "#{base}#{counter}"
+ end
+
+ path
+ end
+ end
+ end
+
+ def up
+ changed_paths = {}
+
+ select_all("SELECT id, username FROM users WHERE username LIKE '%.'").each do |user|
+ username_was = user["username"]
+ username = Namespace.clean_path(username_was)
+ changed_paths[username_was] = username
+
+ username = quote_string(username)
+ execute "UPDATE users SET username = '#{username}' WHERE id = #{user["id"]}"
+ execute "UPDATE namespaces SET path = '#{username}', name = '#{username}' WHERE type IS NULL AND owner_id = #{user["id"]}"
+ end
+
+ select_all("SELECT id, path FROM namespaces WHERE type = 'Group' AND path LIKE '%.'").each do |group|
+ path_was = group["path"]
+ path = Namespace.clean_path(path_was)
+ changed_paths[path_was] = path
+
+ path = quote_string(path)
+ execute "UPDATE namespaces SET path = '#{path}' WHERE id = #{group["id"]}"
+ end
+
+ changed_paths.each do |path_was, path|
+ if gitlab_shell.mv_namespace(path_was, path)
+ # If repositories moved successfully we need to remove old satellites
+ # and send update instructions to users.
+ # However we cannot allow rollback since we moved namespace dir
+ # So we basically we mute exceptions in next actions
+ begin
+ gitlab_shell.rm_satellites(path_was)
+ # We cannot send update instructions since models and mailers
+ # can't safely be used from migrations as they may be written for
+ # later versions of the database.
+ # send_update_instructions
+ rescue
+ # Returning false does not rollback after_* transaction but gives
+ # us information about failing some of tasks
+ false
+ end
+ else
+ # if we cannot move namespace directory we should rollback
+ # db changes in order to prevent out of sync between db and fs
+ raise Exception.new('namespace directory cannot be moved')
+ end
+ end
+ end
+end