summaryrefslogtreecommitdiff
path: root/app/models/project.rb
diff options
context:
space:
mode:
authorDouwe Maan <douwe@gitlab.com>2016-12-09 01:52:36 +0000
committerDouwe Maan <douwe@gitlab.com>2016-12-09 01:52:36 +0000
commit05efd19e8956c5a507bbf22ca74786c1cc0ccc0a (patch)
tree1d020e1ad77f6802c6d16ea6bcee089e0ca3cf3c /app/models/project.rb
parentf23b1cb453deea2659c0cb9e9047c72d859bbf9d (diff)
parent83232be0e14cc8b35bf74532203a6e4371c15e70 (diff)
downloadgitlab-ce-05efd19e8956c5a507bbf22ca74786c1cc0ccc0a.tar.gz
Merge branch 'dz-nested-groups' into 'master'
Add nested groups support on data level ## What does this MR do? - [x] Add `parent_id` field to `Namespace`model. - [x] Create new database table `routes` that keeps information about full path to each group or project - [x] Remove uniq index from `namespaces.path` - [x] Add uniq index on `routes.path` - [x] Fill routes table with path data from namespaces and projects - [x] Change Namespace/Project URL lookup by routes table - [x] Rename related routes (nested groups, projects) when parent path changes This is solely backend preparation. UI, Permissions and API support will be added in separate merge request. ## Are there points in the code the reviewer needs to double check? migrations, Route model, Routable concern Will require downtime. See https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/7121#note_19490281 discussion ## Why was this MR needed? One step further to full nested groups support ## Screenshots (if relevant) No UI changes in this merge request so far ## Does this MR meet the acceptance criteria? - [x] [CHANGELOG](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/CHANGELOG.md) entry added~~ - ~~[Documentation created/updated](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/development/doc_styleguide.md)~~ - ~~API support added~~ - Tests - [x] Added for this feature/bug - [x] All builds are passing - [x] Conform by the [merge request performance guides](http://docs.gitlab.com/ce/development/merge_request_performance_guidelines.html) - [x] Conform by the [style guides](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/CONTRIBUTING.md#style-guides) - [x] Branch has no merge conflicts with `master` (if it does - rebase it please) - [x] [Squashed related commits together](https://git-scm.com/book/en/Git-Tools-Rewriting-History#Squashing-Commits) ## What are the relevant issue numbers? https://gitlab.com/gitlab-org/gitlab-ce/issues/2772 See merge request !7121
Diffstat (limited to 'app/models/project.rb')
-rw-r--r--app/models/project.rb97
1 files changed, 13 insertions, 84 deletions
diff --git a/app/models/project.rb b/app/models/project.rb
index 590885c0177..77d740081c6 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -14,6 +14,7 @@ class Project < ActiveRecord::Base
include TokenAuthenticatable
include ProjectFeaturesCompatibility
include SelectForProjectAuthorization
+ include Routable
extend Gitlab::ConfigHelper
@@ -324,87 +325,6 @@ class Project < ActiveRecord::Base
non_archived.where(table[:name].matches(pattern))
end
- # Finds a single project for the given path.
- #
- # path - The full project path (including namespace path).
- #
- # Returns a Project, or nil if no project could be found.
- def find_with_namespace(path)
- namespace_path, project_path = path.split('/', 2)
-
- return unless namespace_path && project_path
-
- namespace_path = connection.quote(namespace_path)
- project_path = connection.quote(project_path)
-
- # On MySQL we want to ensure the ORDER BY uses a case-sensitive match so
- # any literal matches come first, for this we have to use "BINARY".
- # Without this there's still no guarantee in what order MySQL will return
- # rows.
- binary = Gitlab::Database.mysql? ? 'BINARY' : ''
-
- order_sql = "(CASE WHEN #{binary} namespaces.path = #{namespace_path} " \
- "AND #{binary} projects.path = #{project_path} THEN 0 ELSE 1 END)"
-
- where_paths_in([path]).reorder(order_sql).take
- end
-
- # Builds a relation to find multiple projects by their full paths.
- #
- # Each path must be in the following format:
- #
- # namespace_path/project_path
- #
- # For example:
- #
- # gitlab-org/gitlab-ce
- #
- # Usage:
- #
- # Project.where_paths_in(%w{gitlab-org/gitlab-ce gitlab-org/gitlab-ee})
- #
- # This would return the projects with the full paths matching the values
- # given.
- #
- # paths - An Array of full paths (namespace path + project path) for which
- # to find the projects.
- #
- # Returns an ActiveRecord::Relation.
- def where_paths_in(paths)
- wheres = []
- cast_lower = Gitlab::Database.postgresql?
-
- paths.each do |path|
- namespace_path, project_path = path.split('/', 2)
-
- next unless namespace_path && project_path
-
- namespace_path = connection.quote(namespace_path)
- project_path = connection.quote(project_path)
-
- where = "(namespaces.path = #{namespace_path}
- AND projects.path = #{project_path})"
-
- if cast_lower
- where = "(
- #{where}
- OR (
- LOWER(namespaces.path) = LOWER(#{namespace_path})
- AND LOWER(projects.path) = LOWER(#{project_path})
- )
- )"
- end
-
- wheres << where
- end
-
- if wheres.empty?
- none
- else
- joins(:namespace).where(wheres.join(' OR '))
- end
- end
-
def visibility_levels
Gitlab::VisibilityLevel.options
end
@@ -440,6 +360,10 @@ class Project < ActiveRecord::Base
def group_ids
joins(:namespace).where(namespaces: { type: 'Group' }).select(:namespace_id)
end
+
+ # Add alias for Routable method for compatibility with old code.
+ # In future all calls `find_with_namespace` should be replaced with `find_by_full_path`
+ alias_method :find_with_namespace, :find_by_full_path
end
def lfs_enabled?
@@ -879,13 +803,14 @@ class Project < ActiveRecord::Base
end
alias_method :human_name, :name_with_namespace
- def path_with_namespace
- if namespace
- namespace.path + '/' + path
+ def full_path
+ if namespace && path
+ namespace.full_path + '/' + path
else
path
end
end
+ alias_method :path_with_namespace, :full_path
def execute_hooks(data, hooks_scope = :push_hooks)
hooks.send(hooks_scope).each do |hook|
@@ -1373,4 +1298,8 @@ class Project < ActiveRecord::Base
def validate_board_limit(board)
raise BoardLimitExceeded, 'Number of permitted boards exceeded' if boards.size >= NUMBER_OF_PERMITTED_BOARDS
end
+
+ def full_path_changed?
+ path_changed? || namespace_id_changed?
+ end
end