From 66f9df86d8530b328074df1172348ea6b4af637a Mon Sep 17 00:00:00 2001 From: kjuulh Date: Mon, 14 Feb 2022 22:19:44 +0100 Subject: [PATCH] changed from json projects to m:n --- docker-compose.yml | 1 - services/db/migrations/003_add_projects.sql | 13 +++- services/entry/main.go | 31 ++++++-- .../entry/pkg/application/projects/model.go | 37 +++++++--- .../entry/pkg/application/projects/service.go | 4 +- .../pkg/db/postgres/projectsRepository.go | 74 +++++++++++++------ 6 files changed, 117 insertions(+), 43 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 2d19d29..88a5943 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -9,7 +9,6 @@ x-logging: &loki-logging options: tag: "{{.ImageName}}|{{.Name}}|{{.ImageFullID}}|{{.FullID}}" - services: # Database diff --git a/services/db/migrations/003_add_projects.sql b/services/db/migrations/003_add_projects.sql index e80452b..43bb124 100644 --- a/services/db/migrations/003_add_projects.sql +++ b/services/db/migrations/003_add_projects.sql @@ -2,13 +2,22 @@ create table sctl_project ( - id int GENERATED BY DEFAULT AS IDENTITY primary key, - data jsonb NOT NULL + id int GENERATED BY DEFAULT AS IDENTITY primary key, + 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 ---- drop table sctl_project; +drop table sctl_project_member; -- Write your migrate down statements here. If this migration is irreversible -- Then delete the separator line above. diff --git a/services/entry/main.go b/services/entry/main.go index c7ef98a..c6aaecb 100644 --- a/services/entry/main.go +++ b/services/entry/main.go @@ -140,20 +140,35 @@ func setupApi(l *zap.Logger, cc *cache.MetricCache, us *users.Service, ps *proje return } + type GetProjectMembers struct { + MemberId int `json:"memberId" binding:"required"` + MemberRole string `json:"memberRole" binding:"required"` + } type GetProject struct { - Id int `json:"id" binding:"required"` - Name string `json:"name" binding:"required"` - MemberIds []int `json:"memberIds" binding:"required"` - AdminIds []int `json:"adminIds" binding:"required"` + Id int `json:"id" binding:"required"` + Name string `json:"name" binding:"required"` + Members []*GetProjectMembers `json:"members" 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) for _, p := range projectsArr { getProject = append(getProject, GetProject{ - Id: p.Id, - Name: p.Name, - MemberIds: p.MemberIds, - AdminIds: p.AdminIds, + Id: p.Id, + Name: p.Name, + Members: membersAsGetProjectMembers(p.Members), }) } c.JSON(http.StatusOK, getProject) diff --git a/services/entry/pkg/application/projects/model.go b/services/entry/pkg/application/projects/model.go index ba0aa2b..c480917 100644 --- a/services/entry/pkg/application/projects/model.go +++ b/services/entry/pkg/application/projects/model.go @@ -1,21 +1,38 @@ package projects -type Project struct { - Id int - Name string - MemberIds []int - AdminIds []int +type ProjectMember struct { + MemberId int + Role string } -func NewProject(id int, name string, memberIds []int, adminIds []int) *Project { +type Project struct { + Id int + Name string + Members []ProjectMember +} + +func NewProject(id int, name string, member *ProjectMember) *Project { + members := make([]ProjectMember, 0) + members = append(members, *member) + return &Project{ - Id: id, - Name: name, - MemberIds: memberIds, - AdminIds: adminIds, + Id: id, + Name: name, + Members: members, } } +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 { Name string MemberIds []int diff --git a/services/entry/pkg/application/projects/service.go b/services/entry/pkg/application/projects/service.go index e1c9839..e6ee34a 100644 --- a/services/entry/pkg/application/projects/service.go +++ b/services/entry/pkg/application/projects/service.go @@ -55,5 +55,7 @@ func (s *Service) Get(ctx context.Context, userId int) ([]*Project, error) { return nil, err } - return entry.([]*Project), nil + projects := entry.([]*Project) + + return projects, nil } diff --git a/services/entry/pkg/db/postgres/projectsRepository.go b/services/entry/pkg/db/postgres/projectsRepository.go index 36b83d4..1e49bac 100644 --- a/services/entry/pkg/db/postgres/projectsRepository.go +++ b/services/entry/pkg/db/postgres/projectsRepository.go @@ -2,6 +2,7 @@ package postgres import ( "context" + "github.com/jackc/pgx/v4" "serverctl/pkg/application/projects" "serverctl/pkg/db" ) @@ -17,17 +18,10 @@ func NewProjectsRepository(db *db.Client) projects.Repository { } type projectData struct { - Name string `json:"name"` - MemberIds []int `json:"memberIds"` - AdminIds []int `json:"adminIds"` -} - -func NewProjectData(project *projects.CreateProject) projectData { - return projectData{ - Name: project.Name, - AdminIds: project.AdminIds, - MemberIds: project.MemberIds, - } + ProjectId int + ProjectName string + MemberId int + MemberRole string } 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() 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 { return -1, err } @@ -47,19 +49,49 @@ func (p ProjectsRepository) GetForMemberId(ctx context.Context, memberId int) ([ conn := p.db.GetConn(ctx) defer conn.Release() - rows, _ := conn.Query(ctx, "select id, data from sctl_project") - projectsArr := make([]*projects.Project, 0) - + rows, _ := conn.Query(ctx, ` +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() { - var ( - id int - data projectData - ) - err := rows.Scan(&id, &data) + var pd projectData + err := rows.Scan(&pd.ProjectId, &pd.ProjectName, &pd.MemberId, &pd.MemberRole) if err != nil { 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