From 76018231c66e26190f0b4c8c01d027f00430bc3a Mon Sep 17 00:00:00 2001 From: Yaroslav Vorobiov Date: Wed, 19 Dec 2018 15:03:12 +0200 Subject: [PATCH] satellite project members pagination api (#907) * satellite project members pagination api * rename GetByProjectIDPaged to GetByProjectID * add comment to max limit --- pkg/satellite/projectmembers.go | 6 +-- pkg/satellite/satellitedb/projectmembers.go | 16 ++----- .../satellitedb/projectmembers_test.go | 45 ++----------------- .../satelliteweb/satelliteql/project.go | 16 ++++++- pkg/satellite/service.go | 18 +++++--- 5 files changed, 34 insertions(+), 67 deletions(-) diff --git a/pkg/satellite/projectmembers.go b/pkg/satellite/projectmembers.go index 211b621f8..2299520aa 100644 --- a/pkg/satellite/projectmembers.go +++ b/pkg/satellite/projectmembers.go @@ -14,10 +14,8 @@ import ( type ProjectMembers interface { // GetByMemberID is a method for querying project member from the database by memberID. GetByMemberID(ctx context.Context, memberID uuid.UUID) (*ProjectMember, error) - // GetByProjectID is a method for querying project members from the database by projectID. - GetByProjectID(ctx context.Context, projectID uuid.UUID) ([]ProjectMember, error) - // GetByProjectIDPaged is a method for querying project members from the database by projectID, offset and limit. - GetByProjectIDPaged(ctx context.Context, projectID uuid.UUID, limit, offset int64) ([]ProjectMember, error) + // GetByProjectID is a method for querying project members from the database by projectID, offset and limit. + GetByProjectID(ctx context.Context, projectID uuid.UUID, limit int, offset int64) ([]ProjectMember, error) // Insert is a method for inserting project member into the database. Insert(ctx context.Context, memberID, projectID uuid.UUID) (*ProjectMember, error) // Delete is a method for deleting project member by memberID and projectID from the database. diff --git a/pkg/satellite/satellitedb/projectmembers.go b/pkg/satellite/satellitedb/projectmembers.go index 14083a1e5..2e9dca7d5 100644 --- a/pkg/satellite/satellitedb/projectmembers.go +++ b/pkg/satellite/satellitedb/projectmembers.go @@ -29,22 +29,12 @@ func (pm *projectMembers) GetByMemberID(ctx context.Context, memberID uuid.UUID) return projectMemberFromDBX(projectMemberDbx) } -// GetByProjectID is a method for querying project members from the database by projectID. -func (pm *projectMembers) GetByProjectID(ctx context.Context, projectID uuid.UUID) ([]satellite.ProjectMember, error) { - projectMembersDbx, err := pm.db.All_ProjectMember_By_ProjectId(ctx, dbx.ProjectMember_ProjectId(projectID[:])) - if err != nil { - return nil, err - } - - return projectMembersFromDbxSlice(projectMembersDbx) -} - -// GetByProjectIDPaged is a method for querying project members from the database by projectID, offset and limit. -func (pm *projectMembers) GetByProjectIDPaged(ctx context.Context, projectID uuid.UUID, limit, offset int64) ([]satellite.ProjectMember, error) { +// GetByProjectID is a method for querying project members from the database by projectID, offset and limit. +func (pm *projectMembers) GetByProjectID(ctx context.Context, projectID uuid.UUID, limit int, offset int64) ([]satellite.ProjectMember, error) { projectMembersDbx, err := pm.db.Limited_ProjectMember_By_ProjectId( ctx, dbx.ProjectMember_ProjectId(projectID[:]), - int(limit), + limit, offset) if err != nil { diff --git a/pkg/satellite/satellitedb/projectmembers_test.go b/pkg/satellite/satellitedb/projectmembers_test.go index b3cbbb275..57dc3a696 100644 --- a/pkg/satellite/satellitedb/projectmembers_test.go +++ b/pkg/satellite/satellitedb/projectmembers_test.go @@ -76,19 +76,19 @@ func TestProjectMembersRepository(t *testing.T) { }) t.Run("Get paged", func(t *testing.T) { - members, err := projectMembers.GetByProjectIDPaged(ctx, createdProjects[0].ID, 1, 0) + members, err := projectMembers.GetByProjectID(ctx, createdProjects[0].ID, 1, 0) assert.Nil(t, err) assert.NoError(t, err) assert.NotNil(t, members) assert.Equal(t, 1, len(members)) - members, err = projectMembers.GetByProjectIDPaged(ctx, createdProjects[0].ID, 2, 0) + members, err = projectMembers.GetByProjectID(ctx, createdProjects[0].ID, 2, 0) assert.Nil(t, err) assert.NoError(t, err) assert.NotNil(t, members) assert.Equal(t, 2, len(members)) - members, err = projectMembers.GetByProjectIDPaged(ctx, createdProjects[0].ID, 1, 1) + members, err = projectMembers.GetByProjectID(ctx, createdProjects[0].ID, 1, 1) assert.Nil(t, err) assert.NoError(t, err) assert.NotNil(t, members) @@ -112,45 +112,6 @@ func TestProjectMembersRepository(t *testing.T) { assert.NoError(t, err) assert.Equal(t, originalMember2.ID, selectedMember2.MemberID) }) - - t.Run("Get member by projectID success", func(t *testing.T) { - originalProject1 := createdProjects[0] - projectMembers1, err := projectMembers.GetByProjectID(ctx, originalProject1.ID) - - assert.NotNil(t, projectMembers1) - assert.Equal(t, 2, len(projectMembers1)) - assert.Nil(t, err) - assert.NoError(t, err) - assert.Equal(t, projectMembers1[0].MemberID, createdUsers[0].ID) - assert.Equal(t, projectMembers1[1].MemberID, createdUsers[1].ID) - - originalProject2 := createdProjects[1] - projectMembers2, err := projectMembers.GetByProjectID(ctx, originalProject2.ID) - - assert.NotNil(t, projectMembers2) - assert.Equal(t, 1, len(projectMembers2)) - assert.Nil(t, err) - assert.NoError(t, err) - assert.Equal(t, projectMembers2[0].MemberID, createdUsers[2].ID) - }) - - t.Run("Delete success", func(t *testing.T) { - members, err := projectMembers.GetByProjectID(ctx, createdProjects[0].ID) - assert.NotNil(t, members) - assert.Equal(t, 2, len(members)) - assert.Nil(t, err) - assert.NoError(t, err) - - err = projectMembers.Delete(ctx, members[1].MemberID, members[1].ProjectID) - assert.Nil(t, err) - assert.NoError(t, err) - - members, err = projectMembers.GetByProjectID(ctx, createdProjects[0].ID) - assert.NotNil(t, members) - assert.Equal(t, 1, len(members)) - assert.Nil(t, err) - assert.NoError(t, err) - }) } func prepareUsersAndProjects(ctx context.Context, t *testing.T, users satellite.Users, projects satellite.Projects) ([]*satellite.User, []*satellite.Project) { diff --git a/pkg/satellite/satelliteweb/satelliteql/project.go b/pkg/satellite/satelliteweb/satelliteql/project.go index ae6cd38ae..1238c7577 100644 --- a/pkg/satellite/satelliteweb/satelliteql/project.go +++ b/pkg/satellite/satelliteweb/satelliteql/project.go @@ -19,6 +19,9 @@ const ( // Used in input model fieldIsTermsAccepted = "isTermsAccepted" fieldMembers = "members" + + limit = "limit" + offset = "offset" ) // graphqlProject creates *graphql.Object type representation of satellite.ProjectInfo @@ -63,10 +66,21 @@ func graphqlProject(service *satellite.Service, types Types) *graphql.Object { }, fieldMembers: &graphql.Field{ Type: graphql.NewList(types.ProjectMember()), + Args: graphql.FieldConfigArgument{ + offset: &graphql.ArgumentConfig{ + Type: graphql.NewNonNull(graphql.Int), + }, + limit: &graphql.ArgumentConfig{ + Type: graphql.NewNonNull(graphql.Int), + }, + }, Resolve: func(p graphql.ResolveParams) (interface{}, error) { project, _ := p.Source.(*satellite.Project) - members, err := service.GetProjectMembers(p.Context, project.ID) + offs, _ := p.Args[offset].(int64) + lim, _ := p.Args[limit].(int) + + members, err := service.GetProjectMembers(p.Context, project.ID, lim, offs) if err != nil { return nil, err } diff --git a/pkg/satellite/service.go b/pkg/satellite/service.go index a38553612..9cfc40bd8 100644 --- a/pkg/satellite/service.go +++ b/pkg/satellite/service.go @@ -20,8 +20,8 @@ import ( "storj.io/storj/pkg/utils" ) -// TODO: Use maxLimit in future. -//const maxLimit = 50 +// maxLimit specifies the limit for all paged queries +const maxLimit = 50 // Service is handling accounts related logic type Service struct { @@ -347,17 +347,21 @@ func (s *Service) DeleteProjectMember(ctx context.Context, projectID, userID uui } // GetProjectMembers returns ProjectMembers for given Project -// TODO: add limit and offset parameters -func (s *Service) GetProjectMembers(ctx context.Context, projectID uuid.UUID) ([]ProjectMember, error) { +func (s *Service) GetProjectMembers(ctx context.Context, projectID uuid.UUID, limit int, offset int64) ([]ProjectMember, error) { _, err := GetAuth(ctx) if err != nil { return nil, err } - // TODO: check if limit < maxLimit const + if limit < 0 || offset < 0 { + return nil, errs.New("invalid pagination argument") + } - // TODO: replace GetByProjectID with GetByProjectIDPaged and remove GetByProjectID as redundant - return s.store.ProjectMembers().GetByProjectID(ctx, projectID) + if limit > maxLimit { + limit = maxLimit + } + + return s.store.ProjectMembers().GetByProjectID(ctx, projectID, limit, offset) } // Authorize validates token from context and returns authorized Authorization