You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
184 lines
5.3 KiB
184 lines
5.3 KiB
package mysqldriver
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
"errors"
|
|
"git.aiterp.net/stufflog/server/internal/slerrors"
|
|
"git.aiterp.net/stufflog/server/models"
|
|
sq "github.com/Masterminds/squirrel"
|
|
"github.com/jmoiron/sqlx"
|
|
)
|
|
|
|
type projectRepository struct {
|
|
db *sqlx.DB
|
|
}
|
|
|
|
func (r *projectRepository) Find(ctx context.Context, id string) (*models.Project, error) {
|
|
project := models.Project{}
|
|
err := r.db.GetContext(ctx, &project, "SELECT * FROM project WHERE project_id=?", id)
|
|
if err != nil {
|
|
if err == sql.ErrNoRows {
|
|
return nil, slerrors.NotFound("Project")
|
|
}
|
|
|
|
return nil, err
|
|
}
|
|
|
|
return &project, nil
|
|
}
|
|
|
|
func (r *projectRepository) List(ctx context.Context, filter models.ProjectFilter) ([]*models.Project, error) {
|
|
q := sq.Select("project.*").From("project").OrderBy("project_id")
|
|
if len(filter.ProjectIDs) > 0 {
|
|
q = q.Where(sq.Eq{"project_id": filter.ProjectIDs})
|
|
}
|
|
if filter.Search != nil {
|
|
q = q.Where("MATCH (name, description) AGAINST (?)", *filter.Search)
|
|
}
|
|
if filter.Permission != nil && filter.Permission.Valid() {
|
|
q = q.LeftJoin("project_permission ON project.project_id = project_permission.project_id AND project_permission.user_id = ?", filter.Permission.UserID)
|
|
if filter.Permission.MaxLevel >= filter.Permission.MinLevel {
|
|
q = q.Where(sq.And{
|
|
sq.GtOrEq{"project_permission.access_level": filter.Permission.MinLevel},
|
|
sq.LtOrEq{"project_permission.access_level": filter.Permission.MaxLevel},
|
|
})
|
|
} else {
|
|
q = q.Where(sq.GtOrEq{"project_permission.access_level": filter.Permission.MinLevel})
|
|
}
|
|
}
|
|
|
|
query, args, err := q.ToSql()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
results := make([]*models.Project, 0, 16)
|
|
err = r.db.SelectContext(ctx, &results, query, args...)
|
|
if err != nil {
|
|
if err == sql.ErrNoRows {
|
|
return []*models.Project{}, nil
|
|
}
|
|
|
|
return nil, err
|
|
}
|
|
|
|
return results, nil
|
|
}
|
|
|
|
func (r *projectRepository) Insert(ctx context.Context, project models.Project) (*models.Project, error) {
|
|
if !project.ValidKey() {
|
|
return nil, errors.New("invalid project id")
|
|
}
|
|
|
|
_, err := r.db.NamedExecContext(ctx, `
|
|
INSERT INTO project (project_id, name, description, daily_points)
|
|
VALUES (:project_id, :name, :description, :daily_points)
|
|
`, project)
|
|
|
|
return &project, err
|
|
}
|
|
|
|
func (r *projectRepository) Save(ctx context.Context, project models.Project) error {
|
|
_, err := r.db.NamedExecContext(ctx, `
|
|
UPDATE project
|
|
SET name=:name, description=:description, daily_points=:daily_points
|
|
WHERE project_id=:project_id
|
|
`, project)
|
|
|
|
return err
|
|
}
|
|
|
|
func (r *projectRepository) ListPermissions(ctx context.Context, project models.Project) ([]*models.ProjectPermission, error) {
|
|
permissions := make([]*models.ProjectPermission, 0, 4)
|
|
err := r.db.SelectContext(ctx, &permissions, "SELECT * FROM project_permission WHERE project_id=?", project.ID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return permissions, nil
|
|
}
|
|
|
|
func (r *projectRepository) GetPermission(ctx context.Context, project models.Project, user models.User) (*models.ProjectPermission, error) {
|
|
permission := models.ProjectPermission{}
|
|
err := r.db.GetContext(ctx, &permission, "SELECT * FROM project_permission WHERE project_id=? AND user_id=?", project.ID, user.ID)
|
|
if err != nil {
|
|
if err == sql.ErrNoRows {
|
|
return &models.ProjectPermission{
|
|
ProjectID: project.ID,
|
|
UserID: user.ID,
|
|
Level: models.ProjectPermissionLevelNoAccess,
|
|
}, nil
|
|
}
|
|
|
|
return nil, err
|
|
}
|
|
|
|
return &permission, nil
|
|
}
|
|
|
|
func (r *projectRepository) GetUserPermissions(ctx context.Context, user models.User, projectIDs []string) ([]*models.ProjectPermission, error) {
|
|
query, args, err := sq.Select("*").From("project_permission").Where(sq.Eq{
|
|
"user_id": user.ID,
|
|
"project_id": projectIDs,
|
|
}).ToSql()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
permissions := make([]*models.ProjectPermission, 0, 8)
|
|
err = r.db.SelectContext(ctx, &permissions, query, args...)
|
|
if err != nil && err != sql.ErrNoRows {
|
|
return nil, err
|
|
}
|
|
|
|
filled := make(map[string]bool, len(permissions))
|
|
for _, permission := range permissions {
|
|
filled[permission.ProjectID] = true
|
|
}
|
|
for _, projectID := range projectIDs {
|
|
if filled[projectID] {
|
|
continue
|
|
}
|
|
|
|
permissions = append(permissions, &models.ProjectPermission{
|
|
ProjectID: projectID,
|
|
UserID: user.ID,
|
|
Level: models.ProjectPermissionLevelNoAccess,
|
|
})
|
|
}
|
|
|
|
return permissions, nil
|
|
}
|
|
|
|
func (r *projectRepository) GetIssuePermission(ctx context.Context, issue models.Issue, user models.User) (*models.ProjectPermission, error) {
|
|
return r.GetPermission(ctx, models.Project{ID: issue.ProjectID}, user)
|
|
}
|
|
|
|
func (r *projectRepository) SetPermission(ctx context.Context, permission models.ProjectPermission) error {
|
|
_, err := r.db.NamedExecContext(ctx, `
|
|
REPLACE INTO project_permission (project_id, user_id, access_level)
|
|
VALUES (:project_id, :user_id, :access_level)
|
|
`, permission)
|
|
|
|
return err
|
|
}
|
|
|
|
func (r *projectRepository) Delete(ctx context.Context, project models.Project) error {
|
|
_, err := r.db.ExecContext(ctx, "DELETE FROM project WHERE project_id=?", project.ID)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
_, err = r.db.ExecContext(ctx, "DELETE FROM project_permission WHERE project_id=?", project.ID)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
_, err = r.db.ExecContext(ctx, "DELETE FROM project_status WHERE project_id=?", project.ID)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|