Class: Namespace

Inherits:
ActiveRecord::Base
  • Object
show all
Includes:
Gitlab::ShellAdapter, Sortable
Defined in:
app/models/namespace.rb

Overview

Schema Information

Table name: namespaces

id                    :integer          not null, primary key
name                  :string           not null
path                  :string           not null
owner_id              :integer
created_at            :datetime
updated_at            :datetime
type                  :string
description           :string           default(""), not null
avatar                :string
share_with_group_lock :boolean          default(FALSE)
visibility_level      :integer          default(20), not null

Direct Known Subclasses

Group

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Gitlab::ShellAdapter

#gitlab_shell

Class Method Details

.by_path(path) ⇒ Object


48
49
50
# File 'app/models/namespace.rb', line 48

def by_path(path)
  find_by('lower(path) = :value', value: path.downcase)
end

.clean_path(path) ⇒ Object


71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'app/models/namespace.rb', line 71

def clean_path(path)
  path = path.dup
  # Get the email username by removing everything after an `@` sign.
  path.gsub!(/@.*\z/,             "")
  # Usernames can't end in .git, so remove it.
  path.gsub!(/\.git\z/,           "")
  # Remove dashes at the start of the username.
  path.gsub!(/\A-+/,              "")
  # Remove periods at the end of the username.
  path.gsub!(/\.+\z/,             "")
  # Remove everything that's not in the list of allowed characters.
  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

.find_by_path_or_name(path) ⇒ Object

Case insensetive search for namespace by path or name


53
54
55
# File 'app/models/namespace.rb', line 53

def find_by_path_or_name(path)
  find_by("lower(path) = :path OR lower(name) = :path", path: path.downcase)
end

.search(query) ⇒ Object

Searches for namespaces matching the given query.

This method uses ILIKE on PostgreSQL and LIKE on MySQL.

query - The search query as a String

Returns an ActiveRecord::Relation


64
65
66
67
68
69
# File 'app/models/namespace.rb', line 64

def search(query)
  t = arel_table
  pattern = "%#{query}%"

  where(t[:name].matches(pattern).or(t[:path].matches(pattern)))
end

Instance Method Details

#ensure_dir_existObject


107
108
109
# File 'app/models/namespace.rb', line 107

def ensure_dir_exist
  gitlab_shell.add_namespace(path)
end

#find_fork_of(project) ⇒ Object


161
162
163
# File 'app/models/namespace.rb', line 161

def find_fork_of(project)
  projects.joins(:forked_project_link).find_by('forked_project_links.forked_from_project_id = ?', project.id)
end

#human_nameObject


103
104
105
# File 'app/models/namespace.rb', line 103

def human_name
  owner_name
end

#kindObject


157
158
159
# File 'app/models/namespace.rb', line 157

def kind
  type == 'Group' ? 'group' : 'user'
end

#move_dirObject


126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
# File 'app/models/namespace.rb', line 126

def move_dir
  # Ensure old directory exists before moving it
  gitlab_shell.add_namespace(path_was)

  if gitlab_shell.mv_namespace(path_was, path)
    Gitlab::UploadsTransfer.new.rename_namespace(path_was, path)

    # If repositories moved successfully we need to
    # 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
      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

#rm_dirObject


111
112
113
114
115
116
117
118
119
120
121
122
123
124
# File 'app/models/namespace.rb', line 111

def rm_dir
  # Move namespace directory into trash.
  # We will remove it later async
  new_path = "#{path}+#{id}+deleted"

  if gitlab_shell.mv_namespace(path, new_path)
    message = "Namespace directory \"#{path}\" moved to \"#{new_path}\""
    Gitlab::AppLogger.info message

    # Remove namespace directroy async with delay so
    # GitLab has time to remove all projects first
    GitlabShellWorker.perform_in(5.minutes, :rm_namespace, new_path)
  end
end

#send_update_instructionsObject


151
152
153
154
155
# File 'app/models/namespace.rb', line 151

def send_update_instructions
  projects.each do |project|
    project.send_move_instructions("#{path_was}/#{project.path}")
  end
end

#to_paramObject


99
100
101
# File 'app/models/namespace.rb', line 99

def to_param
  path
end