BigW Consortium Gitlab
Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
G
gitlab-ce
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
Forest Godfrey
gitlab-ce
Commits
8c4d5909
Commit
8c4d5909
authored
Aug 07, 2017
by
Sean McGivern
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'dashboard-projects-controller-query-performance' into 'master'
Improve various parts of Dashboard::ProjectsController See merge request !13319
parents
5bf65c93
bd08fff6
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
125 additions
and
19 deletions
+125
-19
projects_controller.rb
app/controllers/dashboard/projects_controller.rb
+4
-2
projects_helper.rb
app/helpers/projects_helper.rb
+20
-0
user.rb
app/models/user.rb
+13
-11
index.html.haml
app/views/dashboard/projects/index.html.haml
+1
-3
starred.html.haml
app/views/dashboard/projects/starred.html.haml
+1
-1
_new_project_item_select.html.haml
app/views/shared/_new_project_item_select.html.haml
+1
-1
_list.html.haml
app/views/shared/projects/_list.html.haml
+1
-1
dont-use-limit-offset-when-counting-projects.yml
...released/dont-use-limit-offset-when-counting-projects.yml
+4
-0
eager-load-project-creators-for-project-dashboards.yml
...ed/eager-load-project-creators-for-project-dashboards.yml
+4
-0
memoize-user-personal-projects-count.yml
...elogs/unreleased/memoize-user-personal-projects-count.yml
+4
-0
remove-redundant-query-when-retrieving-recent-pushes.yml
.../remove-redundant-query-when-retrieving-recent-pushes.yml
+4
-0
projects_helper_spec.rb
spec/helpers/projects_helper_spec.rb
+44
-0
user_spec.rb
spec/models/user_spec.rb
+24
-0
No files found.
app/controllers/dashboard/projects_controller.rb
View file @
8c4d5909
...
@@ -45,8 +45,10 @@ class Dashboard::ProjectsController < Dashboard::ApplicationController
...
@@ -45,8 +45,10 @@ class Dashboard::ProjectsController < Dashboard::ApplicationController
end
end
def
load_projects
(
finder_params
)
def
load_projects
(
finder_params
)
ProjectsFinder
.
new
(
params:
finder_params
,
current_user:
current_user
)
ProjectsFinder
.
execute
.
includes
(
:route
,
namespace: :route
)
.
new
(
params:
finder_params
,
current_user:
current_user
)
.
execute
.
includes
(
:route
,
:creator
,
namespace: :route
)
end
end
def
load_events
def
load_events
...
...
app/helpers/projects_helper.rb
View file @
8c4d5909
...
@@ -225,6 +225,26 @@ module ProjectsHelper
...
@@ -225,6 +225,26 @@ module ProjectsHelper
end
end
end
end
# Returns true if any projects are present.
#
# If the relation has a LIMIT applied we'll cast the relation to an Array
# since repeated any? checks would otherwise result in multiple COUNT queries
# being executed.
#
# If no limit is applied we'll just issue a COUNT since the result set could
# be too large to load into memory.
def
any_projects?
(
projects
)
if
projects
.
limit_value
projects
.
to_a
.
any?
else
projects
.
except
(
:offset
).
any?
end
end
def
has_projects_or_name?
(
projects
,
params
)
!!
(
params
[
:name
]
||
any_projects?
(
projects
))
end
private
private
def
repo_children_classes
(
field
)
def
repo_children_classes
(
field
)
...
...
app/models/user.rb
View file @
8c4d5909
...
@@ -632,7 +632,11 @@ class User < ActiveRecord::Base
...
@@ -632,7 +632,11 @@ class User < ActiveRecord::Base
end
end
def
projects_limit_left
def
projects_limit_left
projects_limit
-
personal_projects
.
count
projects_limit
-
personal_projects_count
end
def
personal_projects_count
@personal_projects_count
||=
personal_projects
.
count
end
end
def
projects_limit_percent
def
projects_limit_percent
...
@@ -646,16 +650,14 @@ class User < ActiveRecord::Base
...
@@ -646,16 +650,14 @@ class User < ActiveRecord::Base
events
=
events
.
where
(
project_id:
project_ids
)
if
project_ids
events
=
events
.
where
(
project_id:
project_ids
)
if
project_ids
# Use the latest event that has not been pushed or merged recently
# Use the latest event that has not been pushed or merged recently
events
.
recent
.
find
do
|
event
|
events
.
includes
(
:project
).
recent
.
find
do
|
event
|
project
=
Project
.
find_by_id
(
event
.
project_id
)
next
unless
event
.
project
.
repository
.
branch_exists?
(
event
.
branch_name
)
next
unless
project
merge_requests
=
MergeRequest
.
where
(
"created_at >= ?"
,
event
.
created_at
)
if
project
.
repository
.
branch_exists?
(
event
.
branch_name
)
.
where
(
source_project_id:
event
.
project
.
id
,
merge_requests
=
MergeRequest
.
where
(
"created_at >= ?"
,
event
.
created_at
)
source_branch:
event
.
branch_name
)
.
where
(
source_project_id:
project
.
id
,
source_branch:
event
.
branch_name
)
merge_requests
.
empty?
merge_requests
.
empty?
end
end
end
end
end
...
...
app/views/dashboard/projects/index.html.haml
View file @
8c4d5909
...
@@ -13,10 +13,8 @@
...
@@ -13,10 +13,8 @@
-
if
show_callout?
(
'user_callout_dismissed'
)
-
if
show_callout?
(
'user_callout_dismissed'
)
=
render
'shared/user_callout'
=
render
'shared/user_callout'
-
if
@projects
.
any?
||
params
[
:name
]
-
if
has_projects_or_name?
(
@projects
,
params
)
=
render
'dashboard/projects_head'
=
render
'dashboard/projects_head'
-
if
@projects
.
any?
||
params
[
:name
]
=
render
'projects'
=
render
'projects'
-
else
-
else
=
render
"zero_authorized_projects"
=
render
"zero_authorized_projects"
app/views/dashboard/projects/starred.html.haml
View file @
8c4d5909
...
@@ -9,7 +9,7 @@
...
@@ -9,7 +9,7 @@
%div
{
class:
container_class
}
%div
{
class:
container_class
}
=
render
'dashboard/projects_head'
=
render
'dashboard/projects_head'
-
if
@projects
.
any?
||
params
[
:filter_projects
]
-
if
params
[
:filter_projects
]
||
any_projects?
(
@projects
)
=
render
'projects'
=
render
'projects'
-
else
-
else
%h3
You don't have starred projects yet
%h3
You don't have starred projects yet
...
...
app/views/shared/_new_project_item_select.html.haml
View file @
8c4d5909
-
if
@projects
.
any?
-
if
any_projects?
(
@projects
)
.project-item-select-holder
.project-item-select-holder
=
project_select_tag
:project_path
,
class:
"project-item-select"
,
data:
{
include_groups:
local_assigns
[
:include_groups
],
order_by:
'last_activity_at'
,
relative_path:
local_assigns
[
:path
]
},
with_feature_enabled:
local_assigns
[
:with_feature_enabled
]
=
project_select_tag
:project_path
,
class:
"project-item-select"
,
data:
{
include_groups:
local_assigns
[
:include_groups
],
order_by:
'last_activity_at'
,
relative_path:
local_assigns
[
:path
]
},
with_feature_enabled:
local_assigns
[
:with_feature_enabled
]
%a
.btn.btn-new.new-project-item-select-button
%a
.btn.btn-new.new-project-item-select-button
...
...
app/views/shared/projects/_list.html.haml
View file @
8c4d5909
...
@@ -10,7 +10,7 @@
...
@@ -10,7 +10,7 @@
-
load_pipeline_status
(
projects
)
-
load_pipeline_status
(
projects
)
.js-projects-list-holder
.js-projects-list-holder
-
if
projects
.
any?
-
if
any_projects?
(
projects
)
%ul
.projects-list
%ul
.projects-list
-
projects
.
each_with_index
do
|
project
,
i
|
-
projects
.
each_with_index
do
|
project
,
i
|
-
css_class
=
(
i
>=
projects_limit
)
||
project
.
pending_delete?
?
'hide'
:
nil
-
css_class
=
(
i
>=
projects_limit
)
||
project
.
pending_delete?
?
'hide'
:
nil
...
...
changelogs/unreleased/dont-use-limit-offset-when-counting-projects.yml
0 → 100644
View file @
8c4d5909
---
title
:
"
Improve
performance
of
checking
for
projects
on
the
projects
dashboard"
merge_request
:
author
:
changelogs/unreleased/eager-load-project-creators-for-project-dashboards.yml
0 → 100644
View file @
8c4d5909
---
title
:
Eager load project creators for project dashboards
merge_request
:
author
:
changelogs/unreleased/memoize-user-personal-projects-count.yml
0 → 100644
View file @
8c4d5909
---
title
:
Memoize the number of personal projects a user has to reduce COUNT queries
merge_request
:
author
:
changelogs/unreleased/remove-redundant-query-when-retrieving-recent-pushes.yml
0 → 100644
View file @
8c4d5909
---
title
:
Remove redundant query when retrieving the most recent push of a user
merge_request
:
author
:
spec/helpers/projects_helper_spec.rb
View file @
8c4d5909
...
@@ -411,4 +411,48 @@ describe ProjectsHelper do
...
@@ -411,4 +411,48 @@ describe ProjectsHelper do
end
end
end
end
end
end
describe
'#has_projects_or_name?'
do
let
(
:projects
)
do
create
(
:project
)
Project
.
all
end
it
'returns true when there are projects'
do
expect
(
helper
.
has_projects_or_name?
(
projects
,
{})).
to
eq
(
true
)
end
it
'returns true when there are no projects but a name is given'
do
expect
(
helper
.
has_projects_or_name?
(
Project
.
none
,
name:
'foo'
)).
to
eq
(
true
)
end
it
'returns false when there are no projects and there is no name'
do
expect
(
helper
.
has_projects_or_name?
(
Project
.
none
,
{})).
to
eq
(
false
)
end
end
describe
'#any_projects?'
do
before
do
create
(
:project
)
end
it
'returns true when projects will be returned'
do
expect
(
helper
.
any_projects?
(
Project
.
all
)).
to
eq
(
true
)
end
it
'returns false when no projects will be returned'
do
expect
(
helper
.
any_projects?
(
Project
.
none
)).
to
eq
(
false
)
end
it
'only executes a single query when a LIMIT is applied'
do
relation
=
Project
.
limit
(
1
)
recorder
=
ActiveRecord
::
QueryRecorder
.
new
do
2
.
times
do
helper
.
any_projects?
(
relation
)
end
end
expect
(
recorder
.
count
).
to
eq
(
1
)
end
end
end
end
spec/models/user_spec.rb
View file @
8c4d5909
...
@@ -1976,4 +1976,28 @@ describe User do
...
@@ -1976,4 +1976,28 @@ describe User do
expect
(
user
.
allow_password_authentication?
).
to
be_falsey
expect
(
user
.
allow_password_authentication?
).
to
be_falsey
end
end
end
end
describe
'#personal_projects_count'
do
it
'returns the number of personal projects using a single query'
do
user
=
build
(
:user
)
projects
=
double
(
:projects
,
count:
1
)
expect
(
user
).
to
receive
(
:personal_projects
).
once
.
and_return
(
projects
)
2
.
times
do
expect
(
user
.
personal_projects_count
).
to
eq
(
1
)
end
end
end
describe
'#projects_limit_left'
do
it
'returns the number of projects that can be created by the user'
do
user
=
build
(
:user
)
allow
(
user
).
to
receive
(
:projects_limit
).
and_return
(
10
)
allow
(
user
).
to
receive
(
:personal_projects_count
).
and_return
(
5
)
expect
(
user
.
projects_limit_left
).
to
eq
(
5
)
end
end
end
end
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment