2019-01-24 16:26:36 +00:00
|
|
|
// Copyright (C) 2019 Storj Labs, Inc.
|
2018-11-20 14:50:47 +00:00
|
|
|
// See LICENSE for copying information.
|
|
|
|
|
|
|
|
package satellitedb
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
2019-01-31 14:11:53 +00:00
|
|
|
"strings"
|
2018-11-20 14:50:47 +00:00
|
|
|
|
|
|
|
"github.com/skyrings/skyring-common/tools/uuid"
|
|
|
|
"github.com/zeebo/errs"
|
2018-11-29 18:39:27 +00:00
|
|
|
|
2018-11-20 14:50:47 +00:00
|
|
|
"storj.io/storj/pkg/utils"
|
2019-01-15 13:03:24 +00:00
|
|
|
"storj.io/storj/satellite/console"
|
2019-01-16 20:23:28 +00:00
|
|
|
dbx "storj.io/storj/satellite/satellitedb/dbx"
|
2018-11-20 14:50:47 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
// ProjectMembers exposes methods to manage ProjectMembers table in database.
|
|
|
|
type projectMembers struct {
|
2018-12-28 12:07:35 +00:00
|
|
|
methods dbx.Methods
|
|
|
|
db *dbx.DB
|
2018-11-20 14:50:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// GetByMemberID is a method for querying project member from the database by memberID.
|
2019-01-15 13:03:24 +00:00
|
|
|
func (pm *projectMembers) GetByMemberID(ctx context.Context, memberID uuid.UUID) ([]console.ProjectMember, error) {
|
2018-12-28 12:07:35 +00:00
|
|
|
projectMembersDbx, err := pm.methods.All_ProjectMember_By_MemberId(ctx, dbx.ProjectMember_MemberId(memberID[:]))
|
2018-11-20 14:50:47 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2018-12-27 15:30:15 +00:00
|
|
|
return projectMembersFromDbxSlice(projectMembersDbx)
|
2018-11-20 14:50:47 +00:00
|
|
|
}
|
|
|
|
|
2018-12-19 13:03:12 +00:00
|
|
|
// GetByProjectID is a method for querying project members from the database by projectID, offset and limit.
|
2019-01-15 13:03:24 +00:00
|
|
|
func (pm *projectMembers) GetByProjectID(ctx context.Context, projectID uuid.UUID, pagination console.Pagination) ([]console.ProjectMember, error) {
|
2018-12-28 12:07:35 +00:00
|
|
|
if pagination.Limit < 0 || pagination.Offset < 0 {
|
|
|
|
return nil, errs.New("invalid pagination argument")
|
|
|
|
}
|
|
|
|
|
2019-01-15 13:03:24 +00:00
|
|
|
var projectMembers []console.ProjectMember
|
2019-01-31 14:11:53 +00:00
|
|
|
searchSubQuery := "%" + strings.Replace(pagination.Search, " ", "%", -1) + "%"
|
2018-12-28 12:07:35 +00:00
|
|
|
//`+getOrder(pagination.Order)+`
|
|
|
|
|
2019-01-31 13:01:13 +00:00
|
|
|
// TODO: LIKE is case-sensitive postgres, however this should be case-insensitive and possibly allow typos
|
|
|
|
reboundQuery := pm.db.Rebind(`
|
2018-12-28 12:07:35 +00:00
|
|
|
SELECT pm.*
|
|
|
|
FROM project_members pm
|
|
|
|
INNER JOIN users u ON pm.member_id = u.id
|
|
|
|
WHERE pm.project_id = ?
|
|
|
|
AND ( u.email LIKE ? OR
|
2019-03-27 12:33:32 +00:00
|
|
|
u.full_name LIKE ? OR
|
|
|
|
u.short_name LIKE ? )
|
2018-12-28 12:07:35 +00:00
|
|
|
ORDER BY ` + sanitizedOrderColumnName(pagination.Order) + ` ASC
|
|
|
|
LIMIT ? OFFSET ?
|
|
|
|
`)
|
|
|
|
|
2019-01-31 13:01:13 +00:00
|
|
|
rows, err := pm.db.Query(reboundQuery, projectID[:], searchSubQuery, searchSubQuery, searchSubQuery, pagination.Limit, pagination.Offset)
|
2018-12-28 12:07:35 +00:00
|
|
|
|
|
|
|
defer func() {
|
|
|
|
err = errs.Combine(err, rows.Close())
|
|
|
|
}()
|
2018-12-17 14:28:58 +00:00
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2018-12-28 12:07:35 +00:00
|
|
|
for rows.Next() {
|
2019-01-15 13:03:24 +00:00
|
|
|
pm := console.ProjectMember{}
|
2018-12-28 12:07:35 +00:00
|
|
|
var memberIDBytes, projectIDBytes []uint8
|
|
|
|
var memberID, projectID uuid.UUID
|
|
|
|
|
|
|
|
scanErr := rows.Scan(&memberIDBytes, &projectIDBytes, &pm.CreatedAt)
|
|
|
|
if err != nil {
|
|
|
|
err = errs.Combine(err, scanErr)
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
memberID, convertErr := bytesToUUID(memberIDBytes)
|
|
|
|
if convertErr != nil {
|
|
|
|
err = errs.Combine(err, convertErr)
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
projectID, convertErr = bytesToUUID(projectIDBytes)
|
|
|
|
if convertErr != nil {
|
|
|
|
err = errs.Combine(err, convertErr)
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
pm.ProjectID = projectID
|
|
|
|
pm.MemberID = memberID
|
|
|
|
|
|
|
|
projectMembers = append(projectMembers, pm)
|
|
|
|
}
|
|
|
|
|
|
|
|
return projectMembers, err
|
2018-12-17 14:28:58 +00:00
|
|
|
}
|
|
|
|
|
2018-11-20 14:50:47 +00:00
|
|
|
// Insert is a method for inserting project member into the database.
|
2019-01-15 13:03:24 +00:00
|
|
|
func (pm *projectMembers) Insert(ctx context.Context, memberID, projectID uuid.UUID) (*console.ProjectMember, error) {
|
2018-12-28 12:07:35 +00:00
|
|
|
createdProjectMember, err := pm.methods.Create_ProjectMember(ctx,
|
2018-11-20 14:50:47 +00:00
|
|
|
dbx.ProjectMember_MemberId(memberID[:]),
|
|
|
|
dbx.ProjectMember_ProjectId(projectID[:]))
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return projectMemberFromDBX(createdProjectMember)
|
|
|
|
}
|
|
|
|
|
2018-12-10 12:29:01 +00:00
|
|
|
// Delete is a method for deleting project member by memberID and projectID from the database.
|
|
|
|
func (pm *projectMembers) Delete(ctx context.Context, memberID, projectID uuid.UUID) error {
|
2018-12-28 12:07:35 +00:00
|
|
|
_, err := pm.methods.Delete_ProjectMember_By_MemberId_And_ProjectId(
|
2018-12-10 12:29:01 +00:00
|
|
|
ctx,
|
|
|
|
dbx.ProjectMember_MemberId(memberID[:]),
|
|
|
|
dbx.ProjectMember_ProjectId(projectID[:]),
|
|
|
|
)
|
2018-11-20 14:50:47 +00:00
|
|
|
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
// projectMemberFromDBX is used for creating ProjectMember entity from autogenerated dbx.ProjectMember struct
|
2019-01-15 13:03:24 +00:00
|
|
|
func projectMemberFromDBX(projectMember *dbx.ProjectMember) (*console.ProjectMember, error) {
|
2018-11-20 14:50:47 +00:00
|
|
|
if projectMember == nil {
|
|
|
|
return nil, errs.New("projectMember parameter is nil")
|
|
|
|
}
|
|
|
|
|
|
|
|
memberID, err := bytesToUUID(projectMember.MemberId)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
projectID, err := bytesToUUID(projectMember.ProjectId)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2019-01-15 13:03:24 +00:00
|
|
|
return &console.ProjectMember{
|
2018-11-20 14:50:47 +00:00
|
|
|
MemberID: memberID,
|
|
|
|
ProjectID: projectID,
|
|
|
|
CreatedAt: projectMember.CreatedAt,
|
|
|
|
}, nil
|
|
|
|
}
|
|
|
|
|
2018-12-28 12:07:35 +00:00
|
|
|
// sanitizedOrderColumnName return valid order by column
|
2019-01-15 13:03:24 +00:00
|
|
|
func sanitizedOrderColumnName(pmo console.ProjectMemberOrder) string {
|
2018-12-28 12:07:35 +00:00
|
|
|
switch pmo {
|
|
|
|
case 2:
|
|
|
|
return "u.email"
|
|
|
|
case 3:
|
|
|
|
return "u.created_at"
|
|
|
|
default:
|
2019-03-27 12:33:32 +00:00
|
|
|
return "u.full_name"
|
2018-12-28 12:07:35 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-11-20 14:50:47 +00:00
|
|
|
// projectMembersFromDbxSlice is used for creating []ProjectMember entities from autogenerated []*dbx.ProjectMember struct
|
2019-01-15 13:03:24 +00:00
|
|
|
func projectMembersFromDbxSlice(projectMembersDbx []*dbx.ProjectMember) ([]console.ProjectMember, error) {
|
|
|
|
var projectMembers []console.ProjectMember
|
2018-11-20 14:50:47 +00:00
|
|
|
var errors []error
|
|
|
|
|
|
|
|
// Generating []dbo from []dbx and collecting all errors
|
|
|
|
for _, projectMemberDbx := range projectMembersDbx {
|
|
|
|
projectMember, err := projectMemberFromDBX(projectMemberDbx)
|
|
|
|
if err != nil {
|
|
|
|
errors = append(errors, err)
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
projectMembers = append(projectMembers, *projectMember)
|
|
|
|
}
|
|
|
|
|
|
|
|
return projectMembers, utils.CombineErrors(errors...)
|
|
|
|
}
|