stufflog graphql server
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

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.GetContext(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
}