changed from json projects to m:n

This commit is contained in:
Kasper Juul Hermansen 2022-02-14 22:19:44 +01:00
parent e69073ecad
commit 66f9df86d8
Signed by: kjuulh
GPG Key ID: 0F95C140730F2F23
6 changed files with 117 additions and 43 deletions

View File

@ -9,7 +9,6 @@ x-logging: &loki-logging
options: options:
tag: "{{.ImageName}}|{{.Name}}|{{.ImageFullID}}|{{.FullID}}" tag: "{{.ImageName}}|{{.Name}}|{{.ImageFullID}}|{{.FullID}}"
services: services:
# Database # Database

View File

@ -3,12 +3,21 @@
create table sctl_project create table sctl_project
( (
id int GENERATED BY DEFAULT AS IDENTITY primary key, id int GENERATED BY DEFAULT AS IDENTITY primary key,
data jsonb NOT NULL name varchar(30) not null
);
create table sctl_project_member
(
project_id int REFERENCES sctl_project (id) ON UPDATE CASCADE ON DELETE CASCADE,
member_id int REFERENCES sctl_user (id) ON UPDATE CASCADE,
role varchar(20) not null,
CONSTRAINT project_member_pkey PRIMARY KEY (project_id, member_id)
); );
---- create above / drop below ---- ---- create above / drop below ----
drop table sctl_project; drop table sctl_project;
drop table sctl_project_member;
-- Write your migrate down statements here. If this migration is irreversible -- Write your migrate down statements here. If this migration is irreversible
-- Then delete the separator line above. -- Then delete the separator line above.

View File

@ -140,11 +140,27 @@ func setupApi(l *zap.Logger, cc *cache.MetricCache, us *users.Service, ps *proje
return return
} }
type GetProjectMembers struct {
MemberId int `json:"memberId" binding:"required"`
MemberRole string `json:"memberRole" binding:"required"`
}
type GetProject struct { type GetProject struct {
Id int `json:"id" binding:"required"` Id int `json:"id" binding:"required"`
Name string `json:"name" binding:"required"` Name string `json:"name" binding:"required"`
MemberIds []int `json:"memberIds" binding:"required"` Members []*GetProjectMembers `json:"members" binding:"required"`
AdminIds []int `json:"adminIds" binding:"required"` }
membersAsGetProjectMembers := func(projectMembers []projects.ProjectMember) []*GetProjectMembers {
gpm := make([]*GetProjectMembers, len(projectMembers))
for i, pm := range projectMembers {
gpm[i] = &GetProjectMembers{
MemberId: pm.MemberId,
MemberRole: pm.Role,
}
}
return gpm
} }
getProject := make([]GetProject, 0) getProject := make([]GetProject, 0)
@ -152,8 +168,7 @@ func setupApi(l *zap.Logger, cc *cache.MetricCache, us *users.Service, ps *proje
getProject = append(getProject, GetProject{ getProject = append(getProject, GetProject{
Id: p.Id, Id: p.Id,
Name: p.Name, Name: p.Name,
MemberIds: p.MemberIds, Members: membersAsGetProjectMembers(p.Members),
AdminIds: p.AdminIds,
}) })
} }
c.JSON(http.StatusOK, getProject) c.JSON(http.StatusOK, getProject)

View File

@ -1,21 +1,38 @@
package projects package projects
type ProjectMember struct {
MemberId int
Role string
}
type Project struct { type Project struct {
Id int Id int
Name string Name string
MemberIds []int Members []ProjectMember
AdminIds []int
} }
func NewProject(id int, name string, memberIds []int, adminIds []int) *Project { func NewProject(id int, name string, member *ProjectMember) *Project {
members := make([]ProjectMember, 0)
members = append(members, *member)
return &Project{ return &Project{
Id: id, Id: id,
Name: name, Name: name,
MemberIds: memberIds, Members: members,
AdminIds: adminIds,
} }
} }
func NewProjectMember(memberId int, role string) *ProjectMember {
return &ProjectMember{
MemberId: memberId,
Role: role,
}
}
func (p Project) AddMember(member *ProjectMember) {
p.Members = append(p.Members, *member)
}
type CreateProject struct { type CreateProject struct {
Name string Name string
MemberIds []int MemberIds []int

View File

@ -55,5 +55,7 @@ func (s *Service) Get(ctx context.Context, userId int) ([]*Project, error) {
return nil, err return nil, err
} }
return entry.([]*Project), nil projects := entry.([]*Project)
return projects, nil
} }

View File

@ -2,6 +2,7 @@ package postgres
import ( import (
"context" "context"
"github.com/jackc/pgx/v4"
"serverctl/pkg/application/projects" "serverctl/pkg/application/projects"
"serverctl/pkg/db" "serverctl/pkg/db"
) )
@ -17,17 +18,10 @@ func NewProjectsRepository(db *db.Client) projects.Repository {
} }
type projectData struct { type projectData struct {
Name string `json:"name"` ProjectId int
MemberIds []int `json:"memberIds"` ProjectName string
AdminIds []int `json:"adminIds"` MemberId int
} MemberRole string
func NewProjectData(project *projects.CreateProject) projectData {
return projectData{
Name: project.Name,
AdminIds: project.AdminIds,
MemberIds: project.MemberIds,
}
} }
func (p ProjectsRepository) Create(ctx context.Context, project *projects.CreateProject) (int, error) { func (p ProjectsRepository) Create(ctx context.Context, project *projects.CreateProject) (int, error) {
@ -35,7 +29,15 @@ func (p ProjectsRepository) Create(ctx context.Context, project *projects.Create
defer conn.Release() defer conn.Release()
var projectId int var projectId int
err := conn.QueryRow(ctx, "insert into sctl_project(data) values ($1) returning id", NewProjectData(project)).Scan(&projectId) err := conn.BeginTxFunc(ctx, pgx.TxOptions{}, func(tx pgx.Tx) error {
err := tx.QueryRow(ctx, "insert into sctl_project(name) values ($1) returning id", project.Name).Scan(&projectId)
if err != nil {
return err
}
_, err = tx.Exec(ctx, "insert into sctl_project_member(project_id, member_id, role) values($1, $2, $3)", projectId, project.MemberIds[0], "admin")
return err
})
if err != nil { if err != nil {
return -1, err return -1, err
} }
@ -47,19 +49,49 @@ func (p ProjectsRepository) GetForMemberId(ctx context.Context, memberId int) ([
conn := p.db.GetConn(ctx) conn := p.db.GetConn(ctx)
defer conn.Release() defer conn.Release()
rows, _ := conn.Query(ctx, "select id, data from sctl_project") rows, _ := conn.Query(ctx, `
projectsArr := make([]*projects.Project, 0) select pm.project_id, name project_name, pm.member_id, pm.role member_role
from sctl_project
join sctl_project_member pm
on sctl_project.id = pm.project_id
join sctl_user u
on pm.member_id = u.id
where pm.member_id = $1
order by pm.project_id
`, memberId)
projectsDataArr := make([]*projectData, 0)
for rows.Next() { for rows.Next() {
var ( var pd projectData
id int err := rows.Scan(&pd.ProjectId, &pd.ProjectName, &pd.MemberId, &pd.MemberRole)
data projectData
)
err := rows.Scan(&id, &data)
if err != nil { if err != nil {
return nil, err return nil, err
} }
projectsArr = append(projectsArr, projects.NewProject(id, data.Name, data.MemberIds, data.AdminIds)) projectsDataArr = append(projectsDataArr, &pd)
}
projectsArr := make([]*projects.Project, 0)
var tempProject *projects.Project
for _, project := range projectsDataArr {
if tempProject == nil {
tempProject = projects.NewProject(
project.ProjectId,
project.ProjectName,
projects.NewProjectMember(project.MemberId, project.MemberRole),
)
} else if tempProject.Id != project.ProjectId {
projectsArr = append(projectsArr, tempProject)
tempProject = projects.NewProject(
project.ProjectId,
project.ProjectName,
projects.NewProjectMember(project.MemberId, project.MemberRole),
)
} else {
tempProject.AddMember(
projects.NewProjectMember(project.MemberId, project.MemberRole))
}
}
if tempProject != nil {
projectsArr = append(projectsArr, tempProject)
} }
return projectsArr, nil return projectsArr, nil