Commit graph

26 commits

Author SHA1 Message Date
vanadium23
8d44d5142a Add user projects API 2017-07-06 08:04:54 +03:00
Yorick Peterse
c9e277ee01
Refactor GroupProjectsFinder#init_collection
This optimises how GroupProjectsFinder builds it collection, producing
simpler and faster queries in the process. It also cleans up the code a
bit to make it easier to understand.
2017-06-19 19:11:35 +02:00
Yorick Peterse
d29347220c
Refactor ProjectsFinder#init_collection
This changes ProjectsFinder#init_collection so it no longer relies on a
UNION. For example, to get starred projects of a user we used to run:

    SELECT projects.*
    FROM projects
    WHERE projects.pending_delete = 'f'
    AND (
        projects.id IN (
            SELECT projects.id
            FROM projects
            INNER JOIN users_star_projects
                ON users_star_projects.project_id = projects.id
            INNER JOIN project_authorizations
                ON projects.id = project_authorizations.project_id
            WHERE projects.pending_delete = 'f'
            AND project_authorizations.user_id = 1
            AND users_star_projects.user_id = 1

            UNION

            SELECT projects.id
            FROM projects
            INNER JOIN users_star_projects
                ON users_star_projects.project_id = projects.id
            WHERE projects.visibility_level IN (20, 10)
            AND users_star_projects.user_id = 1
        )
    )
    ORDER BY projects.id DESC;

With these changes the above query is turned into the following instead:

    SELECT projects.*
    FROM projects
    INNER JOIN users_star_projects
        ON users_star_projects.project_id = projects.id
    WHERE projects.pending_delete = 'f'
    AND (
        EXISTS (
            SELECT 1
            FROM project_authorizations
            WHERE project_authorizations.user_id = 1
            AND (project_id = projects.id)
        )
        OR projects.visibility_level IN (20,10)
    )
    AND users_star_projects.user_id = 1
    ORDER BY projects.id DESC;

This query in turn produces a better execution plan and takes less time,
though the difference is only a few milliseconds (this however depends
on the amount of data involved and additional conditions that may be
added).
2017-06-16 13:49:09 +02:00
Toon Claes
db679788e4 Add :owned param to ProjectFinder
And use it in the API.
2017-05-30 22:45:59 +02:00
Toon Claes
5654ac877d Make it possible to combine :trending with other params
Now it is possible to combine the :non_public parameter. This might be useful
when a user wants to know the trending projects they are member of.
2017-05-30 22:45:59 +02:00
Toon Claes
01c6323d23 UNION of SELECT/WHERE is faster than WHERE on UNION
Instead of applying WHERE on a UNION, apply the WHERE on each of the seperate
SELECT statements, and do UNION on that.

Local tests with about 2_000_000 projects:
 - 1_500_000 private projects
 -    40_000 internal projects
 -   400_000 public projects

For the API endpoint `/api/v4/projects?visibility=private` the slowest query was:

```sql
SELECT "projects".*
FROM "projects"
WHERE ...
```

The original query took 1073.8ms.
The query refactored to UNION of SELECT/WHERE took 2.3ms.

The original query was:

```sql
SELECT "projects".*
FROM "projects"
WHERE "projects"."pending_delete" = $1
  AND (projects.id IN
         (SELECT "projects"."id"
          FROM "projects"
          INNER JOIN "project_authorizations" ON "projects"."id" = "project_authorizations"."project_id"
          WHERE "projects"."pending_delete" = 'f'
            AND "project_authorizations"."user_id" = 23
          UNION SELECT "projects"."id"
          FROM "projects"
          WHERE "projects"."visibility_level" IN (20,
                                                  10)))
  AND "projects"."visibility_level" = $2
  AND "projects"."archived" = $3
ORDER BY "projects"."created_at" DESC
LIMIT 20
OFFSET 0 [["pending_delete", "f"],
       ["visibility_level", 0],
       ["archived", "f"]]
```

The refactored query:
```sql
SELECT "projects".*
FROM "projects"
WHERE "projects"."pending_delete" = $1
  AND (projects.id IN
         (SELECT "projects"."id"
          FROM "projects"
          INNER JOIN "project_authorizations" ON "projects"."id" = "project_authorizations"."project_id"
          WHERE "projects"."pending_delete" = 'f'
            AND "project_authorizations"."user_id" = 23
            AND "projects"."visibility_level" = 0
            AND "projects"."archived" = 'f'
          UNION SELECT "projects"."id"
          FROM "projects"
          WHERE "projects"."visibility_level" IN (20,
                                                  10)
            AND "projects"."visibility_level" = 0
            AND "projects"."archived" = 'f'))
ORDER BY "projects"."created_at" DESC
LIMIT 20
OFFSET 0 [["pending_delete", "f"]]
```
2017-05-30 22:45:59 +02:00
Toon Claes
0725050802 Change ProjectFinder so starred can be combined with other filters
The `starred` parameter couldn't be used in combination with `trending` or
`non_public`. But this is changed now.
2017-05-30 22:45:59 +02:00
Jacopo
b996a82ff4 ProjectsFinder should handle more options
Extended ProjectFinder in order to handle the following options:
 - current_user - which user use
 - project_ids_relation: int[] - project ids to use
 - params:
   -  trending: boolean
   -  non_public: boolean
   -  starred: boolean
   -  sort: string
   -  visibility_level: int
   -  tags: string[]
   -  personal: boolean
   -  search: string
   -  non_archived: boolean

GroupProjectsFinder now inherits from ProjectsFinder.
Changed the code in order to use the new available options.
2017-04-06 07:11:37 +02:00
Dmitriy Zaporozhets
2989192d1a
Store group and project full name and full path in routes table
Signed-off-by: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>
2017-02-08 19:14:29 +02:00
Ahmad Sherif
76db0dc115 Pass project IDs relation to ProjectsFinder instead of using a block 2016-08-15 12:49:31 +02:00
Ahmad Sherif
d13c36f72d Speed up todos queries by limiting the projects set we join with
Closes #20828
2016-08-15 12:49:31 +02:00
Douwe Maan
8db1292139 Tweaks, refactoring, and specs 2016-03-20 21:04:07 +01:00
Zeger-Jan van de Weg
ab418e27a9 Improve external users feature 2016-03-14 22:06:23 +01:00
Zeger-Jan van de Weg
88f8d3a4d6 Merge branch 'master' into 4009-external-users 2016-03-14 20:08:02 +01:00
Dmitriy Zaporozhets
d324bf8434 Merge branch 'share-project-ce' into 'master'
Bring from EE: Share Project with Group

- [x] Models and migrations
- [x] Logic, UI
- [x] Tests
- [x] Documentation
- [x] Share with group lock
- [x] Api feature
- [x] Api docs
- [x] Api tests

Signed-off-by: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>

For #12831 

cc @DouweM @rspeicher @vsizov

See merge request !3186
2016-03-14 16:38:52 +00:00
Zeger-Jan van de Weg
76eeb316df Create an external users tab on Admin user list
Also incorporates the review into this, mainly spec changes.
2016-03-13 19:10:33 +01:00
Zeger-Jan van de Weg
42fcd3881f External Users
The user has the rights of a public user execpt it can never create a project,
 group, or team. Also it cant view internal projects.
2016-03-13 19:08:04 +01:00
Yorick Peterse
3b76b73ab1 Removed User#project_relations
GitLab EE adds an extra relation that selects a "project_id" column
instead of an "id" column, making it very hard for this method to be
re-used in EE. Since using User#authorized_groups in
ProjectsFinder#all_groups apparently has no performance impact we can
just use it and keep everything compatible with EE.
2016-03-12 15:44:48 +01:00
Yorick Peterse
9e00a23716 Clean up ProjectsFinder for getting user projects
We don't need the extra layer of nesting of UNION queries here (as
User#authorized_projects already returns a UNION'd query).
2016-03-11 15:25:23 -05:00
Dmitriy Zaporozhets
068fd5de8a
Add finders logic and tests for shared projects feature
Signed-off-by: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>
2016-03-11 18:55:17 +01:00
Yorick Peterse
fed059a12d Port GitLab EE ProjectsFinder changes
These changes were added in GitLab EE commit
d39de0ea91b26b8840195e5674b92c353cc16661. The tests were a bit bugged
(they used a non existing group, thus not testing a crucial part) which
I only noticed when porting CE changes to EE.
2015-11-20 15:53:04 +01:00
Yorick Peterse
fbcf3bd3fc Refactor ProjectsFinder to not pluck IDs
This class now uses a UNION (when needed) instead of plucking tens of
thousands of project IDs into memory. The tests have also been
re-written to ensure all different use cases are tested properly
(assuming I didn't forget any cases).

The finder has also been broken up into 3 different finder classes:

* ContributedProjectsFinder: class for getting the projects a user
  contributed to.
* PersonalProjectsFinder: class for getting the personal projects of a
  user.
* ProjectsFinder: class for getting generic projects visible to a given
  user.

Previously a lot of the logic of these finders was handled directly in
the users controller.
2015-11-18 13:05:45 +01:00
Dmitriy Zaporozhets
4f1bb91a75
Fix finder and tests for new membership models
Signed-off-by: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>
2014-09-15 16:45:28 +03:00
Dmitriy Zaporozhets
c69b8e0459
Huge replace of old users_project and users_group references
Signed-off-by: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>
2014-09-14 19:32:51 +03:00
Dmitriy Zaporozhets
0fdce4a52b
Refactor some search scopes to prevent wierd behaviour and PG::Error issues
Signed-off-by: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>
2014-06-05 20:37:35 +03:00
Dmitriy Zaporozhets
645e8d4705
Move services for collecting items to Finders
Signed-off-by: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>
2014-02-25 19:15:08 +02:00