From c226e05f68a84fc628e91f6641ec710dc3908217 Mon Sep 17 00:00:00 2001 From: Kartik Verma Date: Mon, 1 Nov 2021 19:18:30 +0530 Subject: [PATCH 01/12] fix: projects api --- api/handler/v1/project_test.go | 1 + internal/project/project.go | 1 + store/postgres/projects.go | 1 + 3 files changed, 3 insertions(+) create mode 100644 api/handler/v1/project_test.go create mode 100644 internal/project/project.go create mode 100644 store/postgres/projects.go diff --git a/api/handler/v1/project_test.go b/api/handler/v1/project_test.go new file mode 100644 index 000000000..b7b1f993d --- /dev/null +++ b/api/handler/v1/project_test.go @@ -0,0 +1 @@ +package v1 diff --git a/internal/project/project.go b/internal/project/project.go new file mode 100644 index 000000000..7dac6f1ab --- /dev/null +++ b/internal/project/project.go @@ -0,0 +1 @@ +package project diff --git a/store/postgres/projects.go b/store/postgres/projects.go new file mode 100644 index 000000000..bf560bea2 --- /dev/null +++ b/store/postgres/projects.go @@ -0,0 +1 @@ +package postgres From ca11005244d5cf4103dfa7818900aec3263a1c65 Mon Sep 17 00:00:00 2001 From: Kartik Verma Date: Mon, 1 Nov 2021 19:18:56 +0530 Subject: [PATCH 02/12] --ammend --- api/handler/v1/org.go | 8 - api/handler/v1/project.go | 144 ++++++++- api/handler/v1/project_test.go | 284 ++++++++++++++++++ api/handler/v1/util.go | 11 + api/handler/v1/v1.go | 3 +- cmd/serve_api.go | 4 + internal/project/project.go | 57 ++++ ...11028230242_create_projects_table.down.sql | 1 + ...0211028230242_create_projects_table.up.sql | 10 + store/postgres/projects.go | 152 ++++++++++ 10 files changed, 659 insertions(+), 15 deletions(-) create mode 100644 store/postgres/migrations/20211028230242_create_projects_table.down.sql create mode 100644 store/postgres/migrations/20211028230242_create_projects_table.up.sql diff --git a/api/handler/v1/org.go b/api/handler/v1/org.go index 2e60c8e77..e5686fe1e 100644 --- a/api/handler/v1/org.go +++ b/api/handler/v1/org.go @@ -24,14 +24,6 @@ type OrganizationService interface { UpdateOrganization(ctx context.Context, toUpdate org.Organization) (org.Organization, error) } -var ( - grpcInternalServerError = status.Errorf(codes.Internal, internalServerError.Error()) - grpcBadBodyError = status.Error(codes.InvalidArgument, badRequestError.Error()) -) - -// HTTP Codes defined here: -// https://github.com/grpc-ecosystem/grpc-gateway/blob/master/runtime/errors.go#L36 - func (v Dep) ListOrganizations(ctx context.Context, request *shieldv1.ListOrganizationsRequest) (*shieldv1.ListOrganizationsResponse, error) { logger := grpczap.Extract(ctx) var orgs []*shieldv1.Organization diff --git a/api/handler/v1/project.go b/api/handler/v1/project.go index e21d9450b..a7ad3dee0 100644 --- a/api/handler/v1/project.go +++ b/api/handler/v1/project.go @@ -2,25 +2,157 @@ package v1 import ( "context" + "errors" + "strings" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" + grpczap "github.com/grpc-ecosystem/go-grpc-middleware/logging/zap/ctxzap" + "github.com/odpf/shield/internal/project" shieldv1 "go.buf.build/odpf/gw/odpf/proton/odpf/shield/v1" + + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" + "google.golang.org/protobuf/types/known/structpb" + "google.golang.org/protobuf/types/known/timestamppb" ) +var grpcProjectNotFoundErr = status.Errorf(codes.NotFound, "project doesn't exist") + +type ProjectService interface { + GetProject(ctx context.Context, id string) (project.Project, error) + CreateProject(ctx context.Context, project project.Project) (project.Project, error) + ListProject(ctx context.Context) ([]project.Project, error) + UpdateProject(ctx context.Context, toUpdate project.Project) (project.Project, error) +} + func (v Dep) ListProjects(ctx context.Context, request *shieldv1.ListProjectsRequest) (*shieldv1.ListProjectsResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method not implemented") + logger := grpczap.Extract(ctx) + var projects []*shieldv1.Project + + projectList, err := v.ProjectService.ListProject(ctx) + if err != nil { + logger.Error(err.Error()) + return nil, grpcInternalServerError + } + + for _, v := range projectList { + projectPB, err := transformProjectToPB(v) + if err != nil { + logger.Error(err.Error()) + return nil, grpcInternalServerError + } + + projects = append(projects, &projectPB) + } + + return &shieldv1.ListProjectsResponse{Projects: projects}, nil } func (v Dep) CreateProject(ctx context.Context, request *shieldv1.CreateProjectRequest) (*shieldv1.CreateProjectResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method not implemented") + logger := grpczap.Extract(ctx) + metaDataMap, err := mapOfStringValues(request.GetBody().Metadata.AsMap()) + if err != nil { + logger.Error(err.Error()) + return nil, grpcBadBodyError + } + + slug := request.GetBody().Slug + if strings.TrimSpace(slug) == "" { + slug = generateSlug(request.GetBody().Name) + } + + newProject, err := v.ProjectService.CreateProject(ctx, project.Project{ + Name: request.GetBody().Name, + Slug: slug, + Metadata: metaDataMap, + }) + + if err != nil { + logger.Error(err.Error()) + return nil, grpcInternalServerError + } + + metaData, err := structpb.NewStruct(mapOfInterfaceValues(newProject.Metadata)) + if err != nil { + logger.Error(err.Error()) + return nil, grpcInternalServerError + } + + return &shieldv1.CreateProjectResponse{Project: &shieldv1.Project{ + Id: newProject.Id, + Name: newProject.Name, + Slug: newProject.Slug, + Metadata: metaData, + CreatedAt: timestamppb.New(newProject.CreatedAt), + UpdatedAt: timestamppb.New(newProject.UpdatedAt), + }}, nil } func (v Dep) GetProject(ctx context.Context, request *shieldv1.GetProjectRequest) (*shieldv1.GetProjectResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method not implemented") + logger := grpczap.Extract(ctx) + + fetchedProject, err := v.ProjectService.GetProject(ctx, request.GetId()) + if err != nil { + logger.Error(err.Error()) + switch { + case errors.Is(err, project.ProjectDoesntExist): + return nil, grpcProjectNotFoundErr + case errors.Is(err, project.InvalidUUID): + return nil, grpcBadBodyError + default: + return nil, grpcInternalServerError + } + } + + projectPB, err := transformProjectToPB(fetchedProject) + if err != nil { + logger.Error(err.Error()) + return nil, grpcInternalServerError + } + + return &shieldv1.GetProjectResponse{Project: &projectPB}, nil } func (v Dep) UpdateProject(ctx context.Context, request *shieldv1.UpdateProjectRequest) (*shieldv1.UpdateProjectResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method not implemented") + logger := grpczap.Extract(ctx) + + metaDataMap, err := mapOfStringValues(request.GetBody().Metadata.AsMap()) + if err != nil { + return nil, grpcBadBodyError + } + + updatedProject, err := v.ProjectService.UpdateProject(ctx, project.Project{ + Id: request.GetId(), + Name: request.GetBody().Name, + Slug: request.GetBody().Slug, + Metadata: metaDataMap, + }) + if err != nil { + logger.Error(err.Error()) + return nil, grpcInternalServerError + } + + projectPB, err := transformProjectToPB(updatedProject) + if err != nil { + logger.Error(err.Error()) + return nil, grpcInternalServerError + } + + return &shieldv1.UpdateProjectResponse{Project: &projectPB}, nil +} + +func transformProjectToPB(prj project.Project) (shieldv1.Project, error) { + metaData, err := structpb.NewStruct(mapOfInterfaceValues(prj.Metadata)) + if err != nil { + return shieldv1.Project{}, err + } + + return shieldv1.Project{ + Id: prj.Id, + Name: prj.Name, + Slug: prj.Slug, + Metadata: metaData, + CreatedAt: timestamppb.New(prj.CreatedAt), + UpdatedAt: timestamppb.New(prj.UpdatedAt), + }, nil } diff --git a/api/handler/v1/project_test.go b/api/handler/v1/project_test.go index b7b1f993d..4104bf80c 100644 --- a/api/handler/v1/project_test.go +++ b/api/handler/v1/project_test.go @@ -1 +1,285 @@ package v1 + +import ( + "context" + "errors" + "testing" + "time" + + "github.com/odpf/shield/internal/project" + "github.com/stretchr/testify/assert" + + shieldv1 "go.buf.build/odpf/gw/odpf/proton/odpf/shield/v1" + + "google.golang.org/protobuf/types/known/structpb" + "google.golang.org/protobuf/types/known/timestamppb" +) + +var testProjectID = "ab657ae7-8c9e-45eb-9862-dd9ceb6d5c71" + +var testProjectMap = map[string]project.Project{ + "ab657ae7-8c9e-45eb-9862-dd9ceb6d5c71": { + Id: "ab657ae7-8c9e-45eb-9862-dd9ceb6d5c71", + Name: "Prj 1", + Slug: "prj-1", + Metadata: map[string]string{ + "email": "org1@org1.com", + }, + CreatedAt: time.Time{}, + UpdatedAt: time.Time{}, + }, + "c7772c63-fca4-4c7c-bf93-c8f85115de4b": { + Id: "c7772c63-fca4-4c7c-bf93-c8f85115de4b", + Name: "Prj 2", + Slug: "prj-2", + Metadata: map[string]string{ + "email": "org1@org2.com", + }, + CreatedAt: time.Time{}, + UpdatedAt: time.Time{}, + }, +} + +func TestCreateProject(t *testing.T) { + t.Parallel() + + table := []struct { + title string + mockProjectSrv mockProject + req *shieldv1.CreateProjectRequest + want *shieldv1.CreateProjectResponse + err error + }{ + { + title: "error in metadata parsing", + req: &shieldv1.CreateProjectRequest{Body: &shieldv1.ProjectRequestBody{ + Name: "odpf 1", + Slug: "odpf-1", + Metadata: &structpb.Struct{ + Fields: map[string]*structpb.Value{ + "count": structpb.NewNumberValue(10), + }, + }, + }}, + err: grpcBadBodyError, + }, + { + title: "error in service", + req: &shieldv1.CreateProjectRequest{Body: &shieldv1.ProjectRequestBody{ + Name: "odpf 1", + Slug: "odpf-1", + Metadata: &structpb.Struct{ + Fields: map[string]*structpb.Value{ + "team": structpb.NewStringValue("Platforms"), + }, + }, + }}, + mockProjectSrv: mockProject{CreateProjectFunc: func(ctx context.Context, prj project.Project) (project.Project, error) { + return project.Project{}, errors.New("some service error") + }}, + err: grpcInternalServerError, + }, + { + title: "success", + req: &shieldv1.CreateProjectRequest{Body: &shieldv1.ProjectRequestBody{ + Name: "odpf 1", + Slug: "odpf-1", + Metadata: &structpb.Struct{ + Fields: map[string]*structpb.Value{ + "team": structpb.NewStringValue("Platforms"), + }, + }, + }}, + mockProjectSrv: mockProject{CreateProjectFunc: func(ctx context.Context, prj project.Project) (project.Project, error) { + return testProjectMap[testProjectID], nil + }}, + want: &shieldv1.CreateProjectResponse{Project: &shieldv1.Project{ + Id: testProjectMap[testProjectID].Id, + Name: testProjectMap[testProjectID].Name, + Slug: testProjectMap[testProjectID].Slug, + Metadata: &structpb.Struct{ + Fields: map[string]*structpb.Value{ + "email": structpb.NewStringValue("org1@org1.com"), + }, + }, + CreatedAt: timestamppb.New(time.Time{}), + UpdatedAt: timestamppb.New(time.Time{}), + }}, + err: nil, + }, + } + + for _, tt := range table { + t.Run(tt.title, func(t *testing.T) { + t.Parallel() + + mockDep := Dep{ProjectService: tt.mockProjectSrv} + resp, err := mockDep.CreateProject(context.Background(), tt.req) + assert.EqualValues(t, tt.want, resp) + assert.EqualValues(t, tt.err, err) + }) + } +} + +func TestListProjects(t *testing.T) { + t.Parallel() + + table := []struct { + title string + mockProjectSrv mockProject + req *shieldv1.ListProjectsRequest + want *shieldv1.ListProjectsResponse + err error + }{ + { + title: "error in service", + req: &shieldv1.ListProjectsRequest{}, + mockProjectSrv: mockProject{ListProjectFunc: func(ctx context.Context) ([]project.Project, error) { + return []project.Project{}, errors.New("some store error") + }}, + err: grpcInternalServerError, + }, + { + title: "success", + req: &shieldv1.ListProjectsRequest{}, + mockProjectSrv: mockProject{ListProjectFunc: func(ctx context.Context) ([]project.Project, error) { + var prjs []project.Project + + for _, v := range testProjectMap { + prjs = append(prjs, v) + } + + return prjs, nil + }}, + want: &shieldv1.ListProjectsResponse{Projects: []*shieldv1.Project{ + { + Id: "ab657ae7-8c9e-45eb-9862-dd9ceb6d5c71", + Name: "Prj 1", + Slug: "prj-1", + Metadata: &structpb.Struct{ + Fields: map[string]*structpb.Value{ + "email": structpb.NewStringValue("org1@org1.com"), + }, + }, + CreatedAt: timestamppb.New(time.Time{}), + UpdatedAt: timestamppb.New(time.Time{}), + }, + { + Id: "c7772c63-fca4-4c7c-bf93-c8f85115de4b", + Name: "Prj 2", + Slug: "prj-2", + Metadata: &structpb.Struct{ + Fields: map[string]*structpb.Value{ + "email": structpb.NewStringValue("org1@org2.com"), + }, + }, + CreatedAt: timestamppb.New(time.Time{}), + UpdatedAt: timestamppb.New(time.Time{}), + }, + }}, + err: nil, + }, + } + + for _, tt := range table { + t.Run(tt.title, func(t *testing.T) { + t.Parallel() + + mockDep := Dep{ProjectService: tt.mockProjectSrv} + resp, err := mockDep.ListProjects(context.Background(), tt.req) + assert.EqualValues(t, tt.want, resp) + assert.EqualValues(t, tt.err, err) + }) + } +} + +func TestGetProject(t *testing.T) { + t.Parallel() + + table := []struct { + title string + mockProjectSrv mockProject + req *shieldv1.GetProjectRequest + want *shieldv1.GetProjectResponse + err error + }{ + { + title: "project doesnt exist", + req: &shieldv1.GetProjectRequest{}, + mockProjectSrv: mockProject{GetProjectFunc: func(ctx context.Context, id string) (project.Project, error) { + return project.Project{}, project.ProjectDoesntExist + }}, + err: grpcProjectNotFoundErr, + }, + { + title: "uuid syntax error", + req: &shieldv1.GetProjectRequest{}, + mockProjectSrv: mockProject{GetProjectFunc: func(ctx context.Context, id string) (project.Project, error) { + return project.Project{}, project.InvalidUUID + }}, + err: grpcBadBodyError, + }, + { + title: "service error", + req: &shieldv1.GetProjectRequest{}, + mockProjectSrv: mockProject{GetProjectFunc: func(ctx context.Context, id string) (project.Project, error) { + return project.Project{}, errors.New("some error") + }}, + err: grpcInternalServerError, + }, + { + title: "success", + req: &shieldv1.GetProjectRequest{}, + mockProjectSrv: mockProject{GetProjectFunc: func(ctx context.Context, id string) (project.Project, error) { + return testProjectMap[testProjectID], nil + }}, + want: &shieldv1.GetProjectResponse{Project: &shieldv1.Project{ + Id: testProjectMap[testProjectID].Id, + Name: testProjectMap[testProjectID].Name, + Slug: testProjectMap[testProjectID].Slug, + Metadata: &structpb.Struct{ + Fields: map[string]*structpb.Value{ + "email": structpb.NewStringValue("org1@org1.com"), + }, + }, + CreatedAt: timestamppb.New(time.Time{}), + UpdatedAt: timestamppb.New(time.Time{}), + }}, + err: nil, + }, + } + + for _, tt := range table { + t.Run(tt.title, func(t *testing.T) { + t.Parallel() + + mockDep := Dep{ProjectService: tt.mockProjectSrv} + resp, err := mockDep.GetProject(context.Background(), tt.req) + assert.EqualValues(t, tt.want, resp) + assert.EqualValues(t, tt.err, err) + }) + } +} + +type mockProject struct { + GetProjectFunc func(ctx context.Context, id string) (project.Project, error) + CreateProjectFunc func(ctx context.Context, project project.Project) (project.Project, error) + ListProjectFunc func(ctx context.Context) ([]project.Project, error) + UpdateProjectFunc func(ctx context.Context, toUpdate project.Project) (project.Project, error) +} + +func (m mockProject) ListProject(ctx context.Context) ([]project.Project, error) { + return m.ListProjectFunc(ctx) +} + +func (m mockProject) CreateProject(ctx context.Context, project project.Project) (project.Project, error) { + return m.CreateProjectFunc(ctx, project) +} + +func (m mockProject) GetProject(ctx context.Context, id string) (project.Project, error) { + return m.GetProjectFunc(ctx, id) +} + +func (m mockProject) UpdateProject(ctx context.Context, toUpdate project.Project) (project.Project, error) { + return m.UpdateProjectFunc(ctx, toUpdate) +} diff --git a/api/handler/v1/util.go b/api/handler/v1/util.go index 460be25af..206d4e1d5 100644 --- a/api/handler/v1/util.go +++ b/api/handler/v1/util.go @@ -3,6 +3,17 @@ package v1 import ( "fmt" "strings" + + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" +) + +// HTTP Codes defined here: +// https://github.com/grpc-ecosystem/grpc-gateway/blob/master/runtime/errors.go#L36 + +var ( + grpcInternalServerError = status.Errorf(codes.Internal, internalServerError.Error()) + grpcBadBodyError = status.Error(codes.InvalidArgument, badRequestError.Error()) ) func mapOfStringValues(m map[string]interface{}) (map[string]string, error) { diff --git a/api/handler/v1/v1.go b/api/handler/v1/v1.go index 35762d8f0..7a0676885 100644 --- a/api/handler/v1/v1.go +++ b/api/handler/v1/v1.go @@ -11,7 +11,8 @@ import ( type Dep struct { shieldv1.UnimplementedShieldServiceServer - OrgService OrganizationService + OrgService OrganizationService + ProjectService ProjectService } var ( diff --git a/cmd/serve_api.go b/cmd/serve_api.go index ce3da5ef9..6536a1995 100644 --- a/cmd/serve_api.go +++ b/cmd/serve_api.go @@ -8,6 +8,7 @@ import ( v1 "github.com/odpf/shield/api/handler/v1" "github.com/odpf/shield/config" "github.com/odpf/shield/internal/org" + "github.com/odpf/shield/internal/project" "github.com/odpf/shield/store/postgres" "github.com/odpf/salt/log" @@ -44,6 +45,9 @@ func apiCommand(logger log.Logger, appConfig *config.Shield) *cli.Command { OrgService: org.Service{ Store: postgres.NewStore(db), }, + ProjectService: project.Service{ + Store: postgres.NewStore(db), + }, }, }) diff --git a/internal/project/project.go b/internal/project/project.go index 7dac6f1ab..9185cfb24 100644 --- a/internal/project/project.go +++ b/internal/project/project.go @@ -1 +1,58 @@ package project + +import ( + "context" + "errors" + "time" +) + +type Project struct { + Id string + Name string + Slug string + Metadata map[string]string + CreatedAt time.Time + UpdatedAt time.Time +} + +type Service struct { + Store Store +} + +var ( + ProjectDoesntExist = errors.New("org doesn't exist") + InvalidUUID = errors.New("invalid syntax of uuid") +) + +type Store interface { + GetProject(ctx context.Context, id string) (Project, error) + CreateProject(ctx context.Context, org Project) (Project, error) + ListProject(ctx context.Context) ([]Project, error) + UpdateProject(ctx context.Context, toUpdate Project) (Project, error) +} + +func (s Service) GetProject(ctx context.Context, id string) (Project, error) { + return s.Store.GetProject(ctx, id) +} + +func (s Service) CreateProject(ctx context.Context, project Project) (Project, error) { + newOrg, err := s.Store.CreateProject(ctx, Project{ + Name: project.Name, + Slug: project.Slug, + Metadata: project.Metadata, + }) + + if err != nil { + return Project{}, err + } + + return newOrg, nil +} + +func (s Service) ListProject(ctx context.Context) ([]Project, error) { + return s.Store.ListProject(ctx) +} + +func (s Service) UpdateProject(ctx context.Context, toUpdate Project) (Project, error) { + return s.Store.UpdateProject(ctx, toUpdate) +} diff --git a/store/postgres/migrations/20211028230242_create_projects_table.down.sql b/store/postgres/migrations/20211028230242_create_projects_table.down.sql new file mode 100644 index 000000000..bb6a95ca2 --- /dev/null +++ b/store/postgres/migrations/20211028230242_create_projects_table.down.sql @@ -0,0 +1 @@ +DROP TABLE IF EXISTS projects ; diff --git a/store/postgres/migrations/20211028230242_create_projects_table.up.sql b/store/postgres/migrations/20211028230242_create_projects_table.up.sql new file mode 100644 index 000000000..63234bea3 --- /dev/null +++ b/store/postgres/migrations/20211028230242_create_projects_table.up.sql @@ -0,0 +1,10 @@ +CREATE TABLE IF NOT EXISTS projects +( + id uuid PRIMARY KEY DEFAULT uuid_generate_v4(), + name varchar UNIQUE NOT NULL, + slug varchar UNIQUE NOT NULL, + metadata jsonb, + created_at timestamptz NOT NULL DEFAULT NOW(), + updated_at timestamptz NOT NULL DEFAULT NOW(), + deleted_at timestamptz +); diff --git a/store/postgres/projects.go b/store/postgres/projects.go index bf560bea2..f34b23a39 100644 --- a/store/postgres/projects.go +++ b/store/postgres/projects.go @@ -1 +1,153 @@ package postgres + +import ( + "context" + "database/sql" + "encoding/json" + "errors" + "fmt" + "time" + + "github.com/odpf/shield/internal/project" +) + +type Project struct { + Id string `db:"id"` + Name string `db:"name"` + Slug string `db:"slug"` + Metadata []byte `db:"metadata"` + CreatedAt time.Time `db:"created_at"` + UpdatedAt time.Time `db:"updated_at"` +} + +const ( + getProjectsQuery = `SELECT id, name, slug, metadata, created_at, updated_at from projects where id=$1;` + createProjectQuery = `INSERT INTO projects(name, slug, metadata) values($1, $2, $3) RETURNING id, name, slug, metadata, created_at, updated_at;` + listProjectQuery = `SELECT id, name, slug, metadata, created_at, updated_at from projects;` + updateProjectQuery = `UPDATE projects set name = $2, slug = $3, metadata = $4, updated_at = now() where id = $1 RETURNING id, name, slug, metadata, created_at, updated_at;` +) + +func (s Store) GetProject(ctx context.Context, id string) (project.Project, error) { + var fetchedProject Project + err := s.DB.WithTimeout(ctx, func(ctx context.Context) error { + return s.DB.GetContext(ctx, &fetchedProject, getProjectsQuery, id) + }) + + if errors.Is(err, sql.ErrNoRows) { + return project.Project{}, project.ProjectDoesntExist + } else if err != nil && fmt.Sprintf("%s", err.Error()[0:38]) == "pq: invalid input syntax for type uuid" { + // TODO: this uuid syntax is a error defined in db, not in library + // need to look into better ways to implement this + return project.Project{}, project.InvalidUUID + } else if err != nil { + return project.Project{}, fmt.Errorf("%w: %s", dbErr, err) + } + + if err != nil { + return project.Project{}, err + } + + transformedProject, err := transformToProject(fetchedProject) + if err != nil { + return project.Project{}, err + } + + return transformedProject, nil +} + +func (s Store) CreateProject(ctx context.Context, projectToCreate project.Project) (project.Project, error) { + marshaledMetadata, err := json.Marshal(projectToCreate.Metadata) + if err != nil { + return project.Project{}, fmt.Errorf("%w: %s", parseErr, err) + } + + var newProject Project + err = s.DB.WithTimeout(ctx, func(ctx context.Context) error { + return s.DB.GetContext(ctx, &newProject, createProjectQuery, projectToCreate.Name, projectToCreate.Slug, marshaledMetadata) + }) + + if err != nil { + return project.Project{}, fmt.Errorf("%w: %s", dbErr, err) + } + + transformedOrg, err := transformToProject(newProject) + if err != nil { + return project.Project{}, fmt.Errorf("%w: %s", parseErr, err) + } + + return transformedOrg, nil +} + +func (s Store) ListProject(ctx context.Context) ([]project.Project, error) { + var fetchedProjects []Project + err := s.DB.WithTimeout(ctx, func(ctx context.Context) error { + return s.DB.SelectContext(ctx, &fetchedProjects, listProjectQuery) + }) + + if errors.Is(err, sql.ErrNoRows) { + return []project.Project{}, project.ProjectDoesntExist + } + + if err != nil { + return []project.Project{}, fmt.Errorf("%w: %s", dbErr, err) + } + + var transformedProjects []project.Project + + for _, o := range fetchedProjects { + transformedOrg, err := transformToProject(o) + if err != nil { + return []project.Project{}, fmt.Errorf("%w: %s", parseErr, err) + } + + transformedProjects = append(transformedProjects, transformedOrg) + } + + return transformedProjects, nil +} + +func (s Store) UpdateProject(ctx context.Context, toUpdate project.Project) (project.Project, error) { + var updatedProject Project + + marshaledMetadata, err := json.Marshal(toUpdate.Metadata) + if err != nil { + return project.Project{}, fmt.Errorf("%w: %s", parseErr, err) + } + + err = s.DB.WithTimeout(ctx, func(ctx context.Context) error { + return s.DB.GetContext(ctx, &updatedProject, updateProjectQuery, toUpdate.Id, toUpdate.Name, toUpdate.Slug, marshaledMetadata) + }) + + if errors.Is(err, sql.ErrNoRows) { + return project.Project{}, project.ProjectDoesntExist + } else if err != nil && fmt.Sprintf("%s", err.Error()[0:38]) == "pq: invalid input syntax for type uuid" { + // TODO: this uuid syntax is a error defined in db, not in library + // need to look into better ways to implement this + return project.Project{}, project.InvalidUUID + } else if err != nil { + return project.Project{}, fmt.Errorf("%w: %s", dbErr, err) + } + + toUpdate, err = transformToProject(updatedProject) + if err != nil { + return project.Project{}, fmt.Errorf("%s: %w", parseErr, err) + } + + return toUpdate, nil +} + +func transformToProject(from Project) (project.Project, error) { + var unmarshalledMetadata map[string]string + if err := json.Unmarshal(from.Metadata, &unmarshalledMetadata); err != nil { + return project.Project{}, err + } + + return project.Project{ + Id: from.Id, + Name: from.Name, + Slug: from.Slug, + Metadata: unmarshalledMetadata, + CreatedAt: from.CreatedAt, + UpdatedAt: from.UpdatedAt, + }, nil +} From d686e3447fc74ed65f2e13885d598956a281dfbb Mon Sep 17 00:00:00 2001 From: Kartik Verma Date: Sun, 7 Nov 2021 22:48:13 +0530 Subject: [PATCH 03/12] fix: correct error message for ProjectDoesntExist --- internal/project/project.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/project/project.go b/internal/project/project.go index 9185cfb24..f570f652f 100644 --- a/internal/project/project.go +++ b/internal/project/project.go @@ -20,7 +20,7 @@ type Service struct { } var ( - ProjectDoesntExist = errors.New("org doesn't exist") + ProjectDoesntExist = errors.New("project doesn't exist") InvalidUUID = errors.New("invalid syntax of uuid") ) From 34dd42af97d69a52adf27c38e6489a12a02e9899 Mon Sep 17 00:00:00 2001 From: Kartik Verma Date: Sun, 7 Nov 2021 23:37:49 +0530 Subject: [PATCH 04/12] fix: add org_id for project --- api/handler/v1/project.go | 1 + internal/project/project.go | 21 +++++++++++-------- ...0211028230242_create_projects_table.up.sql | 1 + store/postgres/projects.go | 15 ++++++------- 4 files changed, 22 insertions(+), 16 deletions(-) diff --git a/api/handler/v1/project.go b/api/handler/v1/project.go index a7ad3dee0..9df1e9e48 100644 --- a/api/handler/v1/project.go +++ b/api/handler/v1/project.go @@ -65,6 +65,7 @@ func (v Dep) CreateProject(ctx context.Context, request *shieldv1.CreateProjectR Name: request.GetBody().Name, Slug: slug, Metadata: metaDataMap, + //Organization: org.Organization{Id: "ACCEPT"}, }) if err != nil { diff --git a/internal/project/project.go b/internal/project/project.go index f570f652f..8ca05685a 100644 --- a/internal/project/project.go +++ b/internal/project/project.go @@ -3,16 +3,18 @@ package project import ( "context" "errors" + "github.com/odpf/shield/internal/org" "time" ) type Project struct { - Id string - Name string - Slug string - Metadata map[string]string - CreatedAt time.Time - UpdatedAt time.Time + Id string + Name string + Slug string + Organization org.Organization + Metadata map[string]string + CreatedAt time.Time + UpdatedAt time.Time } type Service struct { @@ -37,9 +39,10 @@ func (s Service) GetProject(ctx context.Context, id string) (Project, error) { func (s Service) CreateProject(ctx context.Context, project Project) (Project, error) { newOrg, err := s.Store.CreateProject(ctx, Project{ - Name: project.Name, - Slug: project.Slug, - Metadata: project.Metadata, + Name: project.Name, + Slug: project.Slug, + Metadata: project.Metadata, + Organization: project.Organization, }) if err != nil { diff --git a/store/postgres/migrations/20211028230242_create_projects_table.up.sql b/store/postgres/migrations/20211028230242_create_projects_table.up.sql index 63234bea3..feb7d5503 100644 --- a/store/postgres/migrations/20211028230242_create_projects_table.up.sql +++ b/store/postgres/migrations/20211028230242_create_projects_table.up.sql @@ -3,6 +3,7 @@ CREATE TABLE IF NOT EXISTS projects id uuid PRIMARY KEY DEFAULT uuid_generate_v4(), name varchar UNIQUE NOT NULL, slug varchar UNIQUE NOT NULL, + org_id uuid NOT NULL REFERENCES organizations(id), metadata jsonb, created_at timestamptz NOT NULL DEFAULT NOW(), updated_at timestamptz NOT NULL DEFAULT NOW(), diff --git a/store/postgres/projects.go b/store/postgres/projects.go index f34b23a39..9b7afd60f 100644 --- a/store/postgres/projects.go +++ b/store/postgres/projects.go @@ -15,16 +15,17 @@ type Project struct { Id string `db:"id"` Name string `db:"name"` Slug string `db:"slug"` + OrgId string `db:"org_id"` Metadata []byte `db:"metadata"` CreatedAt time.Time `db:"created_at"` UpdatedAt time.Time `db:"updated_at"` } const ( - getProjectsQuery = `SELECT id, name, slug, metadata, created_at, updated_at from projects where id=$1;` - createProjectQuery = `INSERT INTO projects(name, slug, metadata) values($1, $2, $3) RETURNING id, name, slug, metadata, created_at, updated_at;` - listProjectQuery = `SELECT id, name, slug, metadata, created_at, updated_at from projects;` - updateProjectQuery = `UPDATE projects set name = $2, slug = $3, metadata = $4, updated_at = now() where id = $1 RETURNING id, name, slug, metadata, created_at, updated_at;` + getProjectsQuery = `SELECT id, name, slug, org_id, metadata, created_at, updated_at from projects where id=$1;` + createProjectQuery = `INSERT INTO projects(name, slug, org_id, metadata) values($1, $2, $3, $4) RETURNING id, name, slug, org_id, metadata, created_at, updated_at;` + listProjectQuery = `SELECT id, name, slug, org_id, metadata, created_at, updated_at from projects;` + updateProjectQuery = `UPDATE projects set name = $2, slug = $3, org_id=$4, metadata = $5, updated_at = now() where id = $1 RETURNING id, name, slug, metadata, created_at, updated_at;` ) func (s Store) GetProject(ctx context.Context, id string) (project.Project, error) { @@ -63,7 +64,7 @@ func (s Store) CreateProject(ctx context.Context, projectToCreate project.Projec var newProject Project err = s.DB.WithTimeout(ctx, func(ctx context.Context) error { - return s.DB.GetContext(ctx, &newProject, createProjectQuery, projectToCreate.Name, projectToCreate.Slug, marshaledMetadata) + return s.DB.GetContext(ctx, &newProject, createProjectQuery, projectToCreate.Name, projectToCreate.Slug, projectToCreate.Organization.Id, marshaledMetadata) }) if err != nil { @@ -115,7 +116,7 @@ func (s Store) UpdateProject(ctx context.Context, toUpdate project.Project) (pro } err = s.DB.WithTimeout(ctx, func(ctx context.Context) error { - return s.DB.GetContext(ctx, &updatedProject, updateProjectQuery, toUpdate.Id, toUpdate.Name, toUpdate.Slug, marshaledMetadata) + return s.DB.GetContext(ctx, &updatedProject, updateProjectQuery, toUpdate.Id, toUpdate.Name, toUpdate.Slug, toUpdate.Organization.Id, marshaledMetadata) }) if errors.Is(err, sql.ErrNoRows) { @@ -123,7 +124,7 @@ func (s Store) UpdateProject(ctx context.Context, toUpdate project.Project) (pro } else if err != nil && fmt.Sprintf("%s", err.Error()[0:38]) == "pq: invalid input syntax for type uuid" { // TODO: this uuid syntax is a error defined in db, not in library // need to look into better ways to implement this - return project.Project{}, project.InvalidUUID + return project.Project{}, fmt.Errorf("%w: %s", project.InvalidUUID, err) } else if err != nil { return project.Project{}, fmt.Errorf("%w: %s", dbErr, err) } From 88347cc129e2c2cbdac7dab15d20fed7557e1d0e Mon Sep 17 00:00:00 2001 From: Kartik Verma Date: Sun, 7 Nov 2021 23:38:33 +0530 Subject: [PATCH 05/12] fix: lint issues --- internal/project/project.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/internal/project/project.go b/internal/project/project.go index 8ca05685a..9619f70e5 100644 --- a/internal/project/project.go +++ b/internal/project/project.go @@ -3,8 +3,9 @@ package project import ( "context" "errors" - "github.com/odpf/shield/internal/org" "time" + + "github.com/odpf/shield/internal/org" ) type Project struct { From ed3a3421e1e9fd2b7f21511fbc87a7081b450145 Mon Sep 17 00:00:00 2001 From: Kartik Verma Date: Thu, 11 Nov 2021 15:36:27 +0530 Subject: [PATCH 06/12] fix: refactor Project struct to model package --- api/handler/v1/org.go | 15 +++++----- api/handler/v1/org_test.go | 38 +++++++++++++------------- api/handler/v1/project.go | 20 ++++++++------ api/handler/v1/project_test.go | 50 ++++++++++++++++++---------------- internal/org/org.go | 32 ++++++++-------------- internal/project/project.go | 33 ++++++++-------------- model/v1/v1.go | 22 +++++++++++++++ store/postgres/org.go | 45 +++++++++++++++--------------- store/postgres/projects.go | 50 ++++++++++++++++++---------------- 9 files changed, 158 insertions(+), 147 deletions(-) create mode 100644 model/v1/v1.go diff --git a/api/handler/v1/org.go b/api/handler/v1/org.go index e5686fe1e..d63c3983f 100644 --- a/api/handler/v1/org.go +++ b/api/handler/v1/org.go @@ -8,6 +8,7 @@ import ( grpczap "github.com/grpc-ecosystem/go-grpc-middleware/logging/zap/ctxzap" "github.com/odpf/shield/internal/org" + modelv1 "github.com/odpf/shield/model/v1" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" @@ -18,10 +19,10 @@ import ( ) type OrganizationService interface { - GetOrganization(ctx context.Context, id string) (org.Organization, error) - CreateOrganization(ctx context.Context, org org.Organization) (org.Organization, error) - ListOrganizations(ctx context.Context) ([]org.Organization, error) - UpdateOrganization(ctx context.Context, toUpdate org.Organization) (org.Organization, error) + GetOrganization(ctx context.Context, id string) (modelv1.Organization, error) + CreateOrganization(ctx context.Context, org modelv1.Organization) (modelv1.Organization, error) + ListOrganizations(ctx context.Context) ([]modelv1.Organization, error) + UpdateOrganization(ctx context.Context, toUpdate modelv1.Organization) (modelv1.Organization, error) } func (v Dep) ListOrganizations(ctx context.Context, request *shieldv1.ListOrganizationsRequest) (*shieldv1.ListOrganizationsResponse, error) { @@ -68,7 +69,7 @@ func (v Dep) CreateOrganization(ctx context.Context, request *shieldv1.CreateOrg slug = generateSlug(request.GetBody().Name) } - newOrg, err := v.OrgService.CreateOrganization(ctx, org.Organization{ + newOrg, err := v.OrgService.CreateOrganization(ctx, modelv1.Organization{ Name: request.GetBody().Name, Slug: slug, Metadata: metaDataMap, @@ -134,7 +135,7 @@ func (v Dep) UpdateOrganization(ctx context.Context, request *shieldv1.UpdateOrg return nil, grpcBadBodyError } - updatedOrg, err := v.OrgService.UpdateOrganization(ctx, org.Organization{ + updatedOrg, err := v.OrgService.UpdateOrganization(ctx, modelv1.Organization{ Id: request.GetId(), Name: request.GetBody().Name, Slug: request.GetBody().Slug, @@ -155,7 +156,7 @@ func (v Dep) UpdateOrganization(ctx context.Context, request *shieldv1.UpdateOrg return &shieldv1.UpdateOrganizationResponse{Organization: &orgPB}, nil } -func transformOrgToPB(org org.Organization) (shieldv1.Organization, error) { +func transformOrgToPB(org modelv1.Organization) (shieldv1.Organization, error) { metaData, err := structpb.NewStruct(mapOfInterfaceValues(org.Metadata)) if err != nil { return shieldv1.Organization{}, err diff --git a/api/handler/v1/org_test.go b/api/handler/v1/org_test.go index cf61dbca0..63b35d9a7 100644 --- a/api/handler/v1/org_test.go +++ b/api/handler/v1/org_test.go @@ -6,10 +6,10 @@ import ( "testing" "time" - "github.com/odpf/shield/internal/org" - "github.com/stretchr/testify/assert" + modelv1 "github.com/odpf/shield/model/v1" + "google.golang.org/grpc/codes" "google.golang.org/grpc/status" "google.golang.org/protobuf/types/known/structpb" @@ -18,7 +18,7 @@ import ( shieldv1 "go.buf.build/odpf/gw/odpf/proton/odpf/shield/v1" ) -var testOrgMap = map[string]org.Organization{ +var testOrgMap = map[string]modelv1.Organization{ "9f256f86-31a3-11ec-8d3d-0242ac130003": { Id: "9f256f86-31a3-11ec-8d3d-0242ac130003", Name: "Org 1", @@ -42,15 +42,15 @@ func TestListOrganizations(t *testing.T) { }{ { title: "error in Org Service", - mockOrgSrv: mockOrgSrv{ListOrganizationsFunc: func(ctx context.Context) (organizations []org.Organization, err error) { - return []org.Organization{}, errors.New("some error") + mockOrgSrv: mockOrgSrv{ListOrganizationsFunc: func(ctx context.Context) (organizations []modelv1.Organization, err error) { + return []modelv1.Organization{}, errors.New("some error") }}, want: nil, err: status.Errorf(codes.Internal, internalServerError.Error()), }, { title: "success", - mockOrgSrv: mockOrgSrv{ListOrganizationsFunc: func(ctx context.Context) (organizations []org.Organization, err error) { - var testOrgList []org.Organization + mockOrgSrv: mockOrgSrv{ListOrganizationsFunc: func(ctx context.Context) (organizations []modelv1.Organization, err error) { + var testOrgList []modelv1.Organization for _, o := range testOrgMap { testOrgList = append(testOrgList, o) } @@ -98,8 +98,8 @@ func TestCreateOrganization(t *testing.T) { }{ { title: "error in fetching org list", - mockOrgSrv: mockOrgSrv{CreateOrganizationFunc: func(ctx context.Context, o org.Organization) (org.Organization, error) { - return org.Organization{}, errors.New("some error") + mockOrgSrv: mockOrgSrv{CreateOrganizationFunc: func(ctx context.Context, o modelv1.Organization) (modelv1.Organization, error) { + return modelv1.Organization{}, errors.New("some error") }}, req: &shieldv1.CreateOrganizationRequest{Body: &shieldv1.OrganizationRequestBody{ Name: "some org", @@ -125,8 +125,8 @@ func TestCreateOrganization(t *testing.T) { }, { title: "success", - mockOrgSrv: mockOrgSrv{CreateOrganizationFunc: func(ctx context.Context, o org.Organization) (org.Organization, error) { - return org.Organization{ + mockOrgSrv: mockOrgSrv{CreateOrganizationFunc: func(ctx context.Context, o modelv1.Organization) (modelv1.Organization, error) { + return modelv1.Organization{ Id: "new-abc", Name: "some org", Slug: "abc", @@ -167,24 +167,24 @@ func TestCreateOrganization(t *testing.T) { } type mockOrgSrv struct { - GetOrganizationFunc func(ctx context.Context, id string) (org.Organization, error) - CreateOrganizationFunc func(ctx context.Context, org org.Organization) (org.Organization, error) - ListOrganizationsFunc func(ctx context.Context) ([]org.Organization, error) - UpdateOrganizationFunc func(ctx context.Context, toUpdate org.Organization) (org.Organization, error) + GetOrganizationFunc func(ctx context.Context, id string) (modelv1.Organization, error) + CreateOrganizationFunc func(ctx context.Context, org modelv1.Organization) (modelv1.Organization, error) + ListOrganizationsFunc func(ctx context.Context) ([]modelv1.Organization, error) + UpdateOrganizationFunc func(ctx context.Context, toUpdate modelv1.Organization) (modelv1.Organization, error) } -func (m mockOrgSrv) GetOrganization(ctx context.Context, id string) (org.Organization, error) { +func (m mockOrgSrv) GetOrganization(ctx context.Context, id string) (modelv1.Organization, error) { return m.GetOrganizationFunc(ctx, id) } -func (m mockOrgSrv) CreateOrganization(ctx context.Context, org org.Organization) (org.Organization, error) { +func (m mockOrgSrv) CreateOrganization(ctx context.Context, org modelv1.Organization) (modelv1.Organization, error) { return m.CreateOrganizationFunc(ctx, org) } -func (m mockOrgSrv) ListOrganizations(ctx context.Context) ([]org.Organization, error) { +func (m mockOrgSrv) ListOrganizations(ctx context.Context) ([]modelv1.Organization, error) { return m.ListOrganizationsFunc(ctx) } -func (m mockOrgSrv) UpdateOrganization(ctx context.Context, toUpdate org.Organization) (org.Organization, error) { +func (m mockOrgSrv) UpdateOrganization(ctx context.Context, toUpdate modelv1.Organization) (modelv1.Organization, error) { return m.UpdateOrganizationFunc(ctx, toUpdate) } diff --git a/api/handler/v1/project.go b/api/handler/v1/project.go index 9df1e9e48..728bba491 100644 --- a/api/handler/v1/project.go +++ b/api/handler/v1/project.go @@ -6,23 +6,25 @@ import ( "strings" grpczap "github.com/grpc-ecosystem/go-grpc-middleware/logging/zap/ctxzap" - "github.com/odpf/shield/internal/project" - shieldv1 "go.buf.build/odpf/gw/odpf/proton/odpf/shield/v1" + "github.com/odpf/shield/internal/project" + modelv1 "github.com/odpf/shield/model/v1" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" "google.golang.org/protobuf/types/known/structpb" "google.golang.org/protobuf/types/known/timestamppb" + + shieldv1 "go.buf.build/odpf/gw/odpf/proton/odpf/shield/v1" ) var grpcProjectNotFoundErr = status.Errorf(codes.NotFound, "project doesn't exist") type ProjectService interface { - GetProject(ctx context.Context, id string) (project.Project, error) - CreateProject(ctx context.Context, project project.Project) (project.Project, error) - ListProject(ctx context.Context) ([]project.Project, error) - UpdateProject(ctx context.Context, toUpdate project.Project) (project.Project, error) + GetProject(ctx context.Context, id string) (modelv1.Project, error) + CreateProject(ctx context.Context, project modelv1.Project) (modelv1.Project, error) + ListProject(ctx context.Context) ([]modelv1.Project, error) + UpdateProject(ctx context.Context, toUpdate modelv1.Project) (modelv1.Project, error) } func (v Dep) ListProjects(ctx context.Context, request *shieldv1.ListProjectsRequest) (*shieldv1.ListProjectsResponse, error) { @@ -61,7 +63,7 @@ func (v Dep) CreateProject(ctx context.Context, request *shieldv1.CreateProjectR slug = generateSlug(request.GetBody().Name) } - newProject, err := v.ProjectService.CreateProject(ctx, project.Project{ + newProject, err := v.ProjectService.CreateProject(ctx, modelv1.Project{ Name: request.GetBody().Name, Slug: slug, Metadata: metaDataMap, @@ -122,7 +124,7 @@ func (v Dep) UpdateProject(ctx context.Context, request *shieldv1.UpdateProjectR return nil, grpcBadBodyError } - updatedProject, err := v.ProjectService.UpdateProject(ctx, project.Project{ + updatedProject, err := v.ProjectService.UpdateProject(ctx, modelv1.Project{ Id: request.GetId(), Name: request.GetBody().Name, Slug: request.GetBody().Slug, @@ -142,7 +144,7 @@ func (v Dep) UpdateProject(ctx context.Context, request *shieldv1.UpdateProjectR return &shieldv1.UpdateProjectResponse{Project: &projectPB}, nil } -func transformProjectToPB(prj project.Project) (shieldv1.Project, error) { +func transformProjectToPB(prj modelv1.Project) (shieldv1.Project, error) { metaData, err := structpb.NewStruct(mapOfInterfaceValues(prj.Metadata)) if err != nil { return shieldv1.Project{}, err diff --git a/api/handler/v1/project_test.go b/api/handler/v1/project_test.go index 4104bf80c..bea020230 100644 --- a/api/handler/v1/project_test.go +++ b/api/handler/v1/project_test.go @@ -6,9 +6,11 @@ import ( "testing" "time" - "github.com/odpf/shield/internal/project" "github.com/stretchr/testify/assert" + "github.com/odpf/shield/internal/project" + modelv1 "github.com/odpf/shield/model/v1" + shieldv1 "go.buf.build/odpf/gw/odpf/proton/odpf/shield/v1" "google.golang.org/protobuf/types/known/structpb" @@ -17,7 +19,7 @@ import ( var testProjectID = "ab657ae7-8c9e-45eb-9862-dd9ceb6d5c71" -var testProjectMap = map[string]project.Project{ +var testProjectMap = map[string]modelv1.Project{ "ab657ae7-8c9e-45eb-9862-dd9ceb6d5c71": { Id: "ab657ae7-8c9e-45eb-9862-dd9ceb6d5c71", Name: "Prj 1", @@ -74,8 +76,8 @@ func TestCreateProject(t *testing.T) { }, }, }}, - mockProjectSrv: mockProject{CreateProjectFunc: func(ctx context.Context, prj project.Project) (project.Project, error) { - return project.Project{}, errors.New("some service error") + mockProjectSrv: mockProject{CreateProjectFunc: func(ctx context.Context, prj modelv1.Project) (modelv1.Project, error) { + return modelv1.Project{}, errors.New("some service error") }}, err: grpcInternalServerError, }, @@ -90,7 +92,7 @@ func TestCreateProject(t *testing.T) { }, }, }}, - mockProjectSrv: mockProject{CreateProjectFunc: func(ctx context.Context, prj project.Project) (project.Project, error) { + mockProjectSrv: mockProject{CreateProjectFunc: func(ctx context.Context, prj modelv1.Project) (modelv1.Project, error) { return testProjectMap[testProjectID], nil }}, want: &shieldv1.CreateProjectResponse{Project: &shieldv1.Project{ @@ -134,16 +136,16 @@ func TestListProjects(t *testing.T) { { title: "error in service", req: &shieldv1.ListProjectsRequest{}, - mockProjectSrv: mockProject{ListProjectFunc: func(ctx context.Context) ([]project.Project, error) { - return []project.Project{}, errors.New("some store error") + mockProjectSrv: mockProject{ListProjectFunc: func(ctx context.Context) ([]modelv1.Project, error) { + return []modelv1.Project{}, errors.New("some store error") }}, err: grpcInternalServerError, }, { title: "success", req: &shieldv1.ListProjectsRequest{}, - mockProjectSrv: mockProject{ListProjectFunc: func(ctx context.Context) ([]project.Project, error) { - var prjs []project.Project + mockProjectSrv: mockProject{ListProjectFunc: func(ctx context.Context) ([]modelv1.Project, error) { + var prjs []modelv1.Project for _, v := range testProjectMap { prjs = append(prjs, v) @@ -206,31 +208,31 @@ func TestGetProject(t *testing.T) { { title: "project doesnt exist", req: &shieldv1.GetProjectRequest{}, - mockProjectSrv: mockProject{GetProjectFunc: func(ctx context.Context, id string) (project.Project, error) { - return project.Project{}, project.ProjectDoesntExist + mockProjectSrv: mockProject{GetProjectFunc: func(ctx context.Context, id string) (modelv1.Project, error) { + return modelv1.Project{}, project.ProjectDoesntExist }}, err: grpcProjectNotFoundErr, }, { title: "uuid syntax error", req: &shieldv1.GetProjectRequest{}, - mockProjectSrv: mockProject{GetProjectFunc: func(ctx context.Context, id string) (project.Project, error) { - return project.Project{}, project.InvalidUUID + mockProjectSrv: mockProject{GetProjectFunc: func(ctx context.Context, id string) (modelv1.Project, error) { + return modelv1.Project{}, project.InvalidUUID }}, err: grpcBadBodyError, }, { title: "service error", req: &shieldv1.GetProjectRequest{}, - mockProjectSrv: mockProject{GetProjectFunc: func(ctx context.Context, id string) (project.Project, error) { - return project.Project{}, errors.New("some error") + mockProjectSrv: mockProject{GetProjectFunc: func(ctx context.Context, id string) (modelv1.Project, error) { + return modelv1.Project{}, errors.New("some error") }}, err: grpcInternalServerError, }, { title: "success", req: &shieldv1.GetProjectRequest{}, - mockProjectSrv: mockProject{GetProjectFunc: func(ctx context.Context, id string) (project.Project, error) { + mockProjectSrv: mockProject{GetProjectFunc: func(ctx context.Context, id string) (modelv1.Project, error) { return testProjectMap[testProjectID], nil }}, want: &shieldv1.GetProjectResponse{Project: &shieldv1.Project{ @@ -262,24 +264,24 @@ func TestGetProject(t *testing.T) { } type mockProject struct { - GetProjectFunc func(ctx context.Context, id string) (project.Project, error) - CreateProjectFunc func(ctx context.Context, project project.Project) (project.Project, error) - ListProjectFunc func(ctx context.Context) ([]project.Project, error) - UpdateProjectFunc func(ctx context.Context, toUpdate project.Project) (project.Project, error) + GetProjectFunc func(ctx context.Context, id string) (modelv1.Project, error) + CreateProjectFunc func(ctx context.Context, project modelv1.Project) (modelv1.Project, error) + ListProjectFunc func(ctx context.Context) ([]modelv1.Project, error) + UpdateProjectFunc func(ctx context.Context, toUpdate modelv1.Project) (modelv1.Project, error) } -func (m mockProject) ListProject(ctx context.Context) ([]project.Project, error) { +func (m mockProject) ListProject(ctx context.Context) ([]modelv1.Project, error) { return m.ListProjectFunc(ctx) } -func (m mockProject) CreateProject(ctx context.Context, project project.Project) (project.Project, error) { +func (m mockProject) CreateProject(ctx context.Context, project modelv1.Project) (modelv1.Project, error) { return m.CreateProjectFunc(ctx, project) } -func (m mockProject) GetProject(ctx context.Context, id string) (project.Project, error) { +func (m mockProject) GetProject(ctx context.Context, id string) (modelv1.Project, error) { return m.GetProjectFunc(ctx, id) } -func (m mockProject) UpdateProject(ctx context.Context, toUpdate project.Project) (project.Project, error) { +func (m mockProject) UpdateProject(ctx context.Context, toUpdate modelv1.Project) (modelv1.Project, error) { return m.UpdateProjectFunc(ctx, toUpdate) } diff --git a/internal/org/org.go b/internal/org/org.go index e5934a71d..d764e013e 100644 --- a/internal/org/org.go +++ b/internal/org/org.go @@ -3,17 +3,9 @@ package org import ( "context" "errors" - "time" -) -type Organization struct { - Id string - Name string - Slug string - Metadata map[string]string - CreatedAt time.Time - UpdatedAt time.Time -} + modelv1 "github.com/odpf/shield/model/v1" +) type Service struct { Store Store @@ -25,34 +17,34 @@ var ( ) type Store interface { - GetOrg(ctx context.Context, id string) (Organization, error) - CreateOrg(ctx context.Context, org Organization) (Organization, error) - ListOrg(ctx context.Context) ([]Organization, error) - UpdateOrg(ctx context.Context, toUpdate Organization) (Organization, error) + GetOrg(ctx context.Context, id string) (modelv1.Organization, error) + CreateOrg(ctx context.Context, org modelv1.Organization) (modelv1.Organization, error) + ListOrg(ctx context.Context) ([]modelv1.Organization, error) + UpdateOrg(ctx context.Context, toUpdate modelv1.Organization) (modelv1.Organization, error) } -func (s Service) GetOrganization(ctx context.Context, id string) (Organization, error) { +func (s Service) GetOrganization(ctx context.Context, id string) (modelv1.Organization, error) { return s.Store.GetOrg(ctx, id) } -func (s Service) CreateOrganization(ctx context.Context, org Organization) (Organization, error) { - newOrg, err := s.Store.CreateOrg(ctx, Organization{ +func (s Service) CreateOrganization(ctx context.Context, org modelv1.Organization) (modelv1.Organization, error) { + newOrg, err := s.Store.CreateOrg(ctx, modelv1.Organization{ Name: org.Name, Slug: org.Slug, Metadata: org.Metadata, }) if err != nil { - return Organization{}, err + return modelv1.Organization{}, err } return newOrg, nil } -func (s Service) ListOrganizations(ctx context.Context) ([]Organization, error) { +func (s Service) ListOrganizations(ctx context.Context) ([]modelv1.Organization, error) { return s.Store.ListOrg(ctx) } -func (s Service) UpdateOrganization(ctx context.Context, toUpdate Organization) (Organization, error) { +func (s Service) UpdateOrganization(ctx context.Context, toUpdate modelv1.Organization) (modelv1.Organization, error) { return s.Store.UpdateOrg(ctx, toUpdate) } diff --git a/internal/project/project.go b/internal/project/project.go index 9619f70e5..f41b5640a 100644 --- a/internal/project/project.go +++ b/internal/project/project.go @@ -3,21 +3,10 @@ package project import ( "context" "errors" - "time" - "github.com/odpf/shield/internal/org" + modelv1 "github.com/odpf/shield/model/v1" ) -type Project struct { - Id string - Name string - Slug string - Organization org.Organization - Metadata map[string]string - CreatedAt time.Time - UpdatedAt time.Time -} - type Service struct { Store Store } @@ -28,18 +17,18 @@ var ( ) type Store interface { - GetProject(ctx context.Context, id string) (Project, error) - CreateProject(ctx context.Context, org Project) (Project, error) - ListProject(ctx context.Context) ([]Project, error) - UpdateProject(ctx context.Context, toUpdate Project) (Project, error) + GetProject(ctx context.Context, id string) (modelv1.Project, error) + CreateProject(ctx context.Context, org modelv1.Project) (modelv1.Project, error) + ListProject(ctx context.Context) ([]modelv1.Project, error) + UpdateProject(ctx context.Context, toUpdate modelv1.Project) (modelv1.Project, error) } -func (s Service) GetProject(ctx context.Context, id string) (Project, error) { +func (s Service) GetProject(ctx context.Context, id string) (modelv1.Project, error) { return s.Store.GetProject(ctx, id) } -func (s Service) CreateProject(ctx context.Context, project Project) (Project, error) { - newOrg, err := s.Store.CreateProject(ctx, Project{ +func (s Service) CreateProject(ctx context.Context, project modelv1.Project) (modelv1.Project, error) { + newOrg, err := s.Store.CreateProject(ctx, modelv1.Project{ Name: project.Name, Slug: project.Slug, Metadata: project.Metadata, @@ -47,16 +36,16 @@ func (s Service) CreateProject(ctx context.Context, project Project) (Project, e }) if err != nil { - return Project{}, err + return modelv1.Project{}, err } return newOrg, nil } -func (s Service) ListProject(ctx context.Context) ([]Project, error) { +func (s Service) ListProject(ctx context.Context) ([]modelv1.Project, error) { return s.Store.ListProject(ctx) } -func (s Service) UpdateProject(ctx context.Context, toUpdate Project) (Project, error) { +func (s Service) UpdateProject(ctx context.Context, toUpdate modelv1.Project) (modelv1.Project, error) { return s.Store.UpdateProject(ctx, toUpdate) } diff --git a/model/v1/v1.go b/model/v1/v1.go new file mode 100644 index 000000000..290c2029a --- /dev/null +++ b/model/v1/v1.go @@ -0,0 +1,22 @@ +package v1 + +import "time" + +type Project struct { + Id string + Name string + Slug string + Organization Organization + Metadata map[string]string + CreatedAt time.Time + UpdatedAt time.Time +} + +type Organization struct { + Id string + Name string + Slug string + Metadata map[string]string + CreatedAt time.Time + UpdatedAt time.Time +} diff --git a/store/postgres/org.go b/store/postgres/org.go index 3b03a8631..9c3b54c17 100644 --- a/store/postgres/org.go +++ b/store/postgres/org.go @@ -9,6 +9,7 @@ import ( "time" "github.com/odpf/shield/internal/org" + modelv1 "github.com/odpf/shield/model/v1" "github.com/jmoiron/sqlx" ) @@ -31,12 +32,12 @@ const ( updateOrganizationQuery = `UPDATE organizations set name = $2, slug = $3, metadata = $4, updated_at = now() where id = $1 RETURNING id, name, slug, metadata, created_at, updated_at;` ) -func (s Store) GetOrg(ctx context.Context, id string) (org.Organization, error) { +func (s Store) GetOrg(ctx context.Context, id string) (modelv1.Organization, error) { fetchedOrg, _, err := s.selectOrg(ctx, id, false, nil) return fetchedOrg, err } -func (s Store) selectOrg(ctx context.Context, id string, forUpdate bool, txn *sqlx.Tx) (org.Organization, int, error) { +func (s Store) selectOrg(ctx context.Context, id string, forUpdate bool, txn *sqlx.Tx) (modelv1.Organization, int, error) { var fetchedOrg Organization err := s.DB.WithTimeout(ctx, func(ctx context.Context) error { @@ -48,27 +49,27 @@ func (s Store) selectOrg(ctx context.Context, id string, forUpdate bool, txn *sq }) if errors.Is(err, sql.ErrNoRows) { - return org.Organization{}, -1, org.OrgDoesntExist + return modelv1.Organization{}, -1, org.OrgDoesntExist } else if err != nil && fmt.Sprintf("%s", err.Error()[0:38]) == "pq: invalid input syntax for type uuid" { // TODO: this uuid syntax is a error defined in db, not in library // need to look into better ways to implement this - return org.Organization{}, -1, org.InvalidUUID + return modelv1.Organization{}, -1, org.InvalidUUID } else if err != nil { - return org.Organization{}, -1, fmt.Errorf("%w: %s", dbErr, err) + return modelv1.Organization{}, -1, fmt.Errorf("%w: %s", dbErr, err) } transformedOrg, err := transformToOrg(fetchedOrg) if err != nil { - return org.Organization{}, -1, fmt.Errorf("%w: %s", parseErr, err) + return modelv1.Organization{}, -1, fmt.Errorf("%w: %s", parseErr, err) } return transformedOrg, fetchedOrg.Version, nil } -func (s Store) CreateOrg(ctx context.Context, orgToCreate org.Organization) (org.Organization, error) { +func (s Store) CreateOrg(ctx context.Context, orgToCreate modelv1.Organization) (modelv1.Organization, error) { marshaledMetadata, err := json.Marshal(orgToCreate.Metadata) if err != nil { - return org.Organization{}, fmt.Errorf("%w: %s", parseErr, err) + return modelv1.Organization{}, fmt.Errorf("%w: %s", parseErr, err) } var newOrg Organization @@ -77,37 +78,37 @@ func (s Store) CreateOrg(ctx context.Context, orgToCreate org.Organization) (org }) if err != nil { - return org.Organization{}, fmt.Errorf("%w: %s", dbErr, err) + return modelv1.Organization{}, fmt.Errorf("%w: %s", dbErr, err) } transformedOrg, err := transformToOrg(newOrg) if err != nil { - return org.Organization{}, fmt.Errorf("%w: %s", parseErr, err) + return modelv1.Organization{}, fmt.Errorf("%w: %s", parseErr, err) } return transformedOrg, nil } -func (s Store) ListOrg(ctx context.Context) ([]org.Organization, error) { +func (s Store) ListOrg(ctx context.Context) ([]modelv1.Organization, error) { var fetchedOrgs []Organization err := s.DB.WithTimeout(ctx, func(ctx context.Context) error { return s.DB.SelectContext(ctx, &fetchedOrgs, listOrganizationsQuery) }) if errors.Is(err, sql.ErrNoRows) { - return []org.Organization{}, org.OrgDoesntExist + return []modelv1.Organization{}, org.OrgDoesntExist } if err != nil { - return []org.Organization{}, fmt.Errorf("%w: %s", dbErr, err) + return []modelv1.Organization{}, fmt.Errorf("%w: %s", dbErr, err) } - var transformedOrgs []org.Organization + var transformedOrgs []modelv1.Organization for _, o := range fetchedOrgs { transformedOrg, err := transformToOrg(o) if err != nil { - return []org.Organization{}, fmt.Errorf("%w: %s", parseErr, err) + return []modelv1.Organization{}, fmt.Errorf("%w: %s", parseErr, err) } transformedOrgs = append(transformedOrgs, transformedOrg) @@ -116,12 +117,12 @@ func (s Store) ListOrg(ctx context.Context) ([]org.Organization, error) { return transformedOrgs, nil } -func (s Store) UpdateOrg(ctx context.Context, toUpdate org.Organization) (org.Organization, error) { +func (s Store) UpdateOrg(ctx context.Context, toUpdate modelv1.Organization) (modelv1.Organization, error) { var updatedOrg Organization marshaledMetadata, err := json.Marshal(toUpdate.Metadata) if err != nil { - return org.Organization{}, fmt.Errorf("%w: %s", parseErr, err) + return modelv1.Organization{}, fmt.Errorf("%w: %s", parseErr, err) } err = s.DB.WithTimeout(ctx, func(ctx context.Context) error { @@ -129,24 +130,24 @@ func (s Store) UpdateOrg(ctx context.Context, toUpdate org.Organization) (org.Or }) if err != nil { - return org.Organization{}, fmt.Errorf("%s: %w", txnErr, err) + return modelv1.Organization{}, fmt.Errorf("%s: %w", txnErr, err) } toUpdate, err = transformToOrg(updatedOrg) if err != nil { - return org.Organization{}, fmt.Errorf("%s: %w", parseErr, err) + return modelv1.Organization{}, fmt.Errorf("%s: %w", parseErr, err) } return toUpdate, nil } -func transformToOrg(from Organization) (org.Organization, error) { +func transformToOrg(from Organization) (modelv1.Organization, error) { var unmarshalledMetadata map[string]string if err := json.Unmarshal(from.Metadata, &unmarshalledMetadata); err != nil { - return org.Organization{}, err + return modelv1.Organization{}, err } - return org.Organization{ + return modelv1.Organization{ Id: from.Id, Name: from.Name, Slug: from.Slug, diff --git a/store/postgres/projects.go b/store/postgres/projects.go index 9b7afd60f..a9cba8934 100644 --- a/store/postgres/projects.go +++ b/store/postgres/projects.go @@ -9,6 +9,8 @@ import ( "time" "github.com/odpf/shield/internal/project" + + modelv1 "github.com/odpf/shield/model/v1" ) type Project struct { @@ -28,38 +30,38 @@ const ( updateProjectQuery = `UPDATE projects set name = $2, slug = $3, org_id=$4, metadata = $5, updated_at = now() where id = $1 RETURNING id, name, slug, metadata, created_at, updated_at;` ) -func (s Store) GetProject(ctx context.Context, id string) (project.Project, error) { +func (s Store) GetProject(ctx context.Context, id string) (modelv1.Project, error) { var fetchedProject Project err := s.DB.WithTimeout(ctx, func(ctx context.Context) error { return s.DB.GetContext(ctx, &fetchedProject, getProjectsQuery, id) }) if errors.Is(err, sql.ErrNoRows) { - return project.Project{}, project.ProjectDoesntExist + return modelv1.Project{}, project.ProjectDoesntExist } else if err != nil && fmt.Sprintf("%s", err.Error()[0:38]) == "pq: invalid input syntax for type uuid" { // TODO: this uuid syntax is a error defined in db, not in library // need to look into better ways to implement this - return project.Project{}, project.InvalidUUID + return modelv1.Project{}, project.InvalidUUID } else if err != nil { - return project.Project{}, fmt.Errorf("%w: %s", dbErr, err) + return modelv1.Project{}, fmt.Errorf("%w: %s", dbErr, err) } if err != nil { - return project.Project{}, err + return modelv1.Project{}, err } transformedProject, err := transformToProject(fetchedProject) if err != nil { - return project.Project{}, err + return modelv1.Project{}, err } return transformedProject, nil } -func (s Store) CreateProject(ctx context.Context, projectToCreate project.Project) (project.Project, error) { +func (s Store) CreateProject(ctx context.Context, projectToCreate modelv1.Project) (modelv1.Project, error) { marshaledMetadata, err := json.Marshal(projectToCreate.Metadata) if err != nil { - return project.Project{}, fmt.Errorf("%w: %s", parseErr, err) + return modelv1.Project{}, fmt.Errorf("%w: %s", parseErr, err) } var newProject Project @@ -68,37 +70,37 @@ func (s Store) CreateProject(ctx context.Context, projectToCreate project.Projec }) if err != nil { - return project.Project{}, fmt.Errorf("%w: %s", dbErr, err) + return modelv1.Project{}, fmt.Errorf("%w: %s", dbErr, err) } transformedOrg, err := transformToProject(newProject) if err != nil { - return project.Project{}, fmt.Errorf("%w: %s", parseErr, err) + return modelv1.Project{}, fmt.Errorf("%w: %s", parseErr, err) } return transformedOrg, nil } -func (s Store) ListProject(ctx context.Context) ([]project.Project, error) { +func (s Store) ListProject(ctx context.Context) ([]modelv1.Project, error) { var fetchedProjects []Project err := s.DB.WithTimeout(ctx, func(ctx context.Context) error { return s.DB.SelectContext(ctx, &fetchedProjects, listProjectQuery) }) if errors.Is(err, sql.ErrNoRows) { - return []project.Project{}, project.ProjectDoesntExist + return []modelv1.Project{}, project.ProjectDoesntExist } if err != nil { - return []project.Project{}, fmt.Errorf("%w: %s", dbErr, err) + return []modelv1.Project{}, fmt.Errorf("%w: %s", dbErr, err) } - var transformedProjects []project.Project + var transformedProjects []modelv1.Project for _, o := range fetchedProjects { transformedOrg, err := transformToProject(o) if err != nil { - return []project.Project{}, fmt.Errorf("%w: %s", parseErr, err) + return []modelv1.Project{}, fmt.Errorf("%w: %s", parseErr, err) } transformedProjects = append(transformedProjects, transformedOrg) @@ -107,12 +109,12 @@ func (s Store) ListProject(ctx context.Context) ([]project.Project, error) { return transformedProjects, nil } -func (s Store) UpdateProject(ctx context.Context, toUpdate project.Project) (project.Project, error) { +func (s Store) UpdateProject(ctx context.Context, toUpdate modelv1.Project) (modelv1.Project, error) { var updatedProject Project marshaledMetadata, err := json.Marshal(toUpdate.Metadata) if err != nil { - return project.Project{}, fmt.Errorf("%w: %s", parseErr, err) + return modelv1.Project{}, fmt.Errorf("%w: %s", parseErr, err) } err = s.DB.WithTimeout(ctx, func(ctx context.Context) error { @@ -120,30 +122,30 @@ func (s Store) UpdateProject(ctx context.Context, toUpdate project.Project) (pro }) if errors.Is(err, sql.ErrNoRows) { - return project.Project{}, project.ProjectDoesntExist + return modelv1.Project{}, project.ProjectDoesntExist } else if err != nil && fmt.Sprintf("%s", err.Error()[0:38]) == "pq: invalid input syntax for type uuid" { // TODO: this uuid syntax is a error defined in db, not in library // need to look into better ways to implement this - return project.Project{}, fmt.Errorf("%w: %s", project.InvalidUUID, err) + return modelv1.Project{}, fmt.Errorf("%w: %s", project.InvalidUUID, err) } else if err != nil { - return project.Project{}, fmt.Errorf("%w: %s", dbErr, err) + return modelv1.Project{}, fmt.Errorf("%w: %s", dbErr, err) } toUpdate, err = transformToProject(updatedProject) if err != nil { - return project.Project{}, fmt.Errorf("%s: %w", parseErr, err) + return modelv1.Project{}, fmt.Errorf("%s: %w", parseErr, err) } return toUpdate, nil } -func transformToProject(from Project) (project.Project, error) { +func transformToProject(from Project) (modelv1.Project, error) { var unmarshalledMetadata map[string]string if err := json.Unmarshal(from.Metadata, &unmarshalledMetadata); err != nil { - return project.Project{}, err + return modelv1.Project{}, err } - return project.Project{ + return modelv1.Project{ Id: from.Id, Name: from.Name, Slug: from.Slug, From d34b00206b0fdda45430a1cdaba11ebb2c38bf34 Mon Sep 17 00:00:00 2001 From: Kartik Verma Date: Thu, 11 Nov 2021 15:41:07 +0530 Subject: [PATCH 07/12] fix: refactor Project Service interface --- api/handler/v1/project.go | 16 ++++++++-------- api/handler/v1/project_test.go | 8 ++++---- internal/project/project.go | 8 ++++---- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/api/handler/v1/project.go b/api/handler/v1/project.go index 728bba491..259e3a6b9 100644 --- a/api/handler/v1/project.go +++ b/api/handler/v1/project.go @@ -21,17 +21,17 @@ import ( var grpcProjectNotFoundErr = status.Errorf(codes.NotFound, "project doesn't exist") type ProjectService interface { - GetProject(ctx context.Context, id string) (modelv1.Project, error) - CreateProject(ctx context.Context, project modelv1.Project) (modelv1.Project, error) - ListProject(ctx context.Context) ([]modelv1.Project, error) - UpdateProject(ctx context.Context, toUpdate modelv1.Project) (modelv1.Project, error) + Get(ctx context.Context, id string) (modelv1.Project, error) + Create(ctx context.Context, project modelv1.Project) (modelv1.Project, error) + List(ctx context.Context) ([]modelv1.Project, error) + Update(ctx context.Context, toUpdate modelv1.Project) (modelv1.Project, error) } func (v Dep) ListProjects(ctx context.Context, request *shieldv1.ListProjectsRequest) (*shieldv1.ListProjectsResponse, error) { logger := grpczap.Extract(ctx) var projects []*shieldv1.Project - projectList, err := v.ProjectService.ListProject(ctx) + projectList, err := v.ProjectService.List(ctx) if err != nil { logger.Error(err.Error()) return nil, grpcInternalServerError @@ -63,7 +63,7 @@ func (v Dep) CreateProject(ctx context.Context, request *shieldv1.CreateProjectR slug = generateSlug(request.GetBody().Name) } - newProject, err := v.ProjectService.CreateProject(ctx, modelv1.Project{ + newProject, err := v.ProjectService.Create(ctx, modelv1.Project{ Name: request.GetBody().Name, Slug: slug, Metadata: metaDataMap, @@ -94,7 +94,7 @@ func (v Dep) CreateProject(ctx context.Context, request *shieldv1.CreateProjectR func (v Dep) GetProject(ctx context.Context, request *shieldv1.GetProjectRequest) (*shieldv1.GetProjectResponse, error) { logger := grpczap.Extract(ctx) - fetchedProject, err := v.ProjectService.GetProject(ctx, request.GetId()) + fetchedProject, err := v.ProjectService.Get(ctx, request.GetId()) if err != nil { logger.Error(err.Error()) switch { @@ -124,7 +124,7 @@ func (v Dep) UpdateProject(ctx context.Context, request *shieldv1.UpdateProjectR return nil, grpcBadBodyError } - updatedProject, err := v.ProjectService.UpdateProject(ctx, modelv1.Project{ + updatedProject, err := v.ProjectService.Update(ctx, modelv1.Project{ Id: request.GetId(), Name: request.GetBody().Name, Slug: request.GetBody().Slug, diff --git a/api/handler/v1/project_test.go b/api/handler/v1/project_test.go index bea020230..be0e26765 100644 --- a/api/handler/v1/project_test.go +++ b/api/handler/v1/project_test.go @@ -270,18 +270,18 @@ type mockProject struct { UpdateProjectFunc func(ctx context.Context, toUpdate modelv1.Project) (modelv1.Project, error) } -func (m mockProject) ListProject(ctx context.Context) ([]modelv1.Project, error) { +func (m mockProject) List(ctx context.Context) ([]modelv1.Project, error) { return m.ListProjectFunc(ctx) } -func (m mockProject) CreateProject(ctx context.Context, project modelv1.Project) (modelv1.Project, error) { +func (m mockProject) Create(ctx context.Context, project modelv1.Project) (modelv1.Project, error) { return m.CreateProjectFunc(ctx, project) } -func (m mockProject) GetProject(ctx context.Context, id string) (modelv1.Project, error) { +func (m mockProject) Get(ctx context.Context, id string) (modelv1.Project, error) { return m.GetProjectFunc(ctx, id) } -func (m mockProject) UpdateProject(ctx context.Context, toUpdate modelv1.Project) (modelv1.Project, error) { +func (m mockProject) Update(ctx context.Context, toUpdate modelv1.Project) (modelv1.Project, error) { return m.UpdateProjectFunc(ctx, toUpdate) } diff --git a/internal/project/project.go b/internal/project/project.go index f41b5640a..416f97d85 100644 --- a/internal/project/project.go +++ b/internal/project/project.go @@ -23,11 +23,11 @@ type Store interface { UpdateProject(ctx context.Context, toUpdate modelv1.Project) (modelv1.Project, error) } -func (s Service) GetProject(ctx context.Context, id string) (modelv1.Project, error) { +func (s Service) Get(ctx context.Context, id string) (modelv1.Project, error) { return s.Store.GetProject(ctx, id) } -func (s Service) CreateProject(ctx context.Context, project modelv1.Project) (modelv1.Project, error) { +func (s Service) Create(ctx context.Context, project modelv1.Project) (modelv1.Project, error) { newOrg, err := s.Store.CreateProject(ctx, modelv1.Project{ Name: project.Name, Slug: project.Slug, @@ -42,10 +42,10 @@ func (s Service) CreateProject(ctx context.Context, project modelv1.Project) (mo return newOrg, nil } -func (s Service) ListProject(ctx context.Context) ([]modelv1.Project, error) { +func (s Service) List(ctx context.Context) ([]modelv1.Project, error) { return s.Store.ListProject(ctx) } -func (s Service) UpdateProject(ctx context.Context, toUpdate modelv1.Project) (modelv1.Project, error) { +func (s Service) Update(ctx context.Context, toUpdate modelv1.Project) (modelv1.Project, error) { return s.Store.UpdateProject(ctx, toUpdate) } From d35ad05c70d79c9ac4f5108c71c891595a9aa06a Mon Sep 17 00:00:00 2001 From: Kartik Verma Date: Thu, 11 Nov 2021 16:07:42 +0530 Subject: [PATCH 08/12] refactor: Org Service --- api/handler/v1/org.go | 16 ++++++++-------- api/handler/v1/org_test.go | 8 ++++---- internal/org/org.go | 8 ++++---- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/api/handler/v1/org.go b/api/handler/v1/org.go index d63c3983f..6808997fd 100644 --- a/api/handler/v1/org.go +++ b/api/handler/v1/org.go @@ -19,17 +19,17 @@ import ( ) type OrganizationService interface { - GetOrganization(ctx context.Context, id string) (modelv1.Organization, error) - CreateOrganization(ctx context.Context, org modelv1.Organization) (modelv1.Organization, error) - ListOrganizations(ctx context.Context) ([]modelv1.Organization, error) - UpdateOrganization(ctx context.Context, toUpdate modelv1.Organization) (modelv1.Organization, error) + Get(ctx context.Context, id string) (modelv1.Organization, error) + Create(ctx context.Context, org modelv1.Organization) (modelv1.Organization, error) + List(ctx context.Context) ([]modelv1.Organization, error) + Update(ctx context.Context, toUpdate modelv1.Organization) (modelv1.Organization, error) } func (v Dep) ListOrganizations(ctx context.Context, request *shieldv1.ListOrganizationsRequest) (*shieldv1.ListOrganizationsResponse, error) { logger := grpczap.Extract(ctx) var orgs []*shieldv1.Organization - orgList, err := v.OrgService.ListOrganizations(ctx) + orgList, err := v.OrgService.List(ctx) if err != nil { logger.Error(err.Error()) return nil, grpcInternalServerError @@ -69,7 +69,7 @@ func (v Dep) CreateOrganization(ctx context.Context, request *shieldv1.CreateOrg slug = generateSlug(request.GetBody().Name) } - newOrg, err := v.OrgService.CreateOrganization(ctx, modelv1.Organization{ + newOrg, err := v.OrgService.Create(ctx, modelv1.Organization{ Name: request.GetBody().Name, Slug: slug, Metadata: metaDataMap, @@ -99,7 +99,7 @@ func (v Dep) CreateOrganization(ctx context.Context, request *shieldv1.CreateOrg func (v Dep) GetOrganization(ctx context.Context, request *shieldv1.GetOrganizationRequest) (*shieldv1.GetOrganizationResponse, error) { logger := grpczap.Extract(ctx) - fetchedOrg, err := v.OrgService.GetOrganization(ctx, request.GetId()) + fetchedOrg, err := v.OrgService.Get(ctx, request.GetId()) if err != nil { logger.Error(err.Error()) switch { @@ -135,7 +135,7 @@ func (v Dep) UpdateOrganization(ctx context.Context, request *shieldv1.UpdateOrg return nil, grpcBadBodyError } - updatedOrg, err := v.OrgService.UpdateOrganization(ctx, modelv1.Organization{ + updatedOrg, err := v.OrgService.Update(ctx, modelv1.Organization{ Id: request.GetId(), Name: request.GetBody().Name, Slug: request.GetBody().Slug, diff --git a/api/handler/v1/org_test.go b/api/handler/v1/org_test.go index 63b35d9a7..ae314cbf7 100644 --- a/api/handler/v1/org_test.go +++ b/api/handler/v1/org_test.go @@ -173,18 +173,18 @@ type mockOrgSrv struct { UpdateOrganizationFunc func(ctx context.Context, toUpdate modelv1.Organization) (modelv1.Organization, error) } -func (m mockOrgSrv) GetOrganization(ctx context.Context, id string) (modelv1.Organization, error) { +func (m mockOrgSrv) Get(ctx context.Context, id string) (modelv1.Organization, error) { return m.GetOrganizationFunc(ctx, id) } -func (m mockOrgSrv) CreateOrganization(ctx context.Context, org modelv1.Organization) (modelv1.Organization, error) { +func (m mockOrgSrv) Create(ctx context.Context, org modelv1.Organization) (modelv1.Organization, error) { return m.CreateOrganizationFunc(ctx, org) } -func (m mockOrgSrv) ListOrganizations(ctx context.Context) ([]modelv1.Organization, error) { +func (m mockOrgSrv) List(ctx context.Context) ([]modelv1.Organization, error) { return m.ListOrganizationsFunc(ctx) } -func (m mockOrgSrv) UpdateOrganization(ctx context.Context, toUpdate modelv1.Organization) (modelv1.Organization, error) { +func (m mockOrgSrv) Update(ctx context.Context, toUpdate modelv1.Organization) (modelv1.Organization, error) { return m.UpdateOrganizationFunc(ctx, toUpdate) } diff --git a/internal/org/org.go b/internal/org/org.go index d764e013e..1822e8c3c 100644 --- a/internal/org/org.go +++ b/internal/org/org.go @@ -23,11 +23,11 @@ type Store interface { UpdateOrg(ctx context.Context, toUpdate modelv1.Organization) (modelv1.Organization, error) } -func (s Service) GetOrganization(ctx context.Context, id string) (modelv1.Organization, error) { +func (s Service) Get(ctx context.Context, id string) (modelv1.Organization, error) { return s.Store.GetOrg(ctx, id) } -func (s Service) CreateOrganization(ctx context.Context, org modelv1.Organization) (modelv1.Organization, error) { +func (s Service) Create(ctx context.Context, org modelv1.Organization) (modelv1.Organization, error) { newOrg, err := s.Store.CreateOrg(ctx, modelv1.Organization{ Name: org.Name, Slug: org.Slug, @@ -41,10 +41,10 @@ func (s Service) CreateOrganization(ctx context.Context, org modelv1.Organizatio return newOrg, nil } -func (s Service) ListOrganizations(ctx context.Context) ([]modelv1.Organization, error) { +func (s Service) List(ctx context.Context) ([]modelv1.Organization, error) { return s.Store.ListOrg(ctx) } -func (s Service) UpdateOrganization(ctx context.Context, toUpdate modelv1.Organization) (modelv1.Organization, error) { +func (s Service) Update(ctx context.Context, toUpdate modelv1.Organization) (modelv1.Organization, error) { return s.Store.UpdateOrg(ctx, toUpdate) } From 1f63a36d99d804019b318774c0215b3639ce8bf2 Mon Sep 17 00:00:00 2001 From: Kartik Verma Date: Thu, 11 Nov 2021 16:37:22 +0530 Subject: [PATCH 09/12] refactor: Not use versioning for models --- api/handler/v1/org.go | 16 +++++------ api/handler/v1/org_test.go | 36 +++++++++++------------ api/handler/v1/project.go | 16 +++++------ api/handler/v1/project_test.go | 52 +++++++++++++++++----------------- internal/org/org.go | 22 +++++++------- internal/project/project.go | 22 +++++++------- model/{v1/v1.go => model.go} | 2 +- store/postgres/org.go | 50 ++++++++++++++++---------------- store/postgres/projects.go | 51 ++++++++++++++++----------------- 9 files changed, 133 insertions(+), 134 deletions(-) rename model/{v1/v1.go => model.go} (96%) diff --git a/api/handler/v1/org.go b/api/handler/v1/org.go index 6808997fd..418f1ac95 100644 --- a/api/handler/v1/org.go +++ b/api/handler/v1/org.go @@ -8,7 +8,7 @@ import ( grpczap "github.com/grpc-ecosystem/go-grpc-middleware/logging/zap/ctxzap" "github.com/odpf/shield/internal/org" - modelv1 "github.com/odpf/shield/model/v1" + "github.com/odpf/shield/model" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" @@ -19,10 +19,10 @@ import ( ) type OrganizationService interface { - Get(ctx context.Context, id string) (modelv1.Organization, error) - Create(ctx context.Context, org modelv1.Organization) (modelv1.Organization, error) - List(ctx context.Context) ([]modelv1.Organization, error) - Update(ctx context.Context, toUpdate modelv1.Organization) (modelv1.Organization, error) + Get(ctx context.Context, id string) (model.Organization, error) + Create(ctx context.Context, org model.Organization) (model.Organization, error) + List(ctx context.Context) ([]model.Organization, error) + Update(ctx context.Context, toUpdate model.Organization) (model.Organization, error) } func (v Dep) ListOrganizations(ctx context.Context, request *shieldv1.ListOrganizationsRequest) (*shieldv1.ListOrganizationsResponse, error) { @@ -69,7 +69,7 @@ func (v Dep) CreateOrganization(ctx context.Context, request *shieldv1.CreateOrg slug = generateSlug(request.GetBody().Name) } - newOrg, err := v.OrgService.Create(ctx, modelv1.Organization{ + newOrg, err := v.OrgService.Create(ctx, model.Organization{ Name: request.GetBody().Name, Slug: slug, Metadata: metaDataMap, @@ -135,7 +135,7 @@ func (v Dep) UpdateOrganization(ctx context.Context, request *shieldv1.UpdateOrg return nil, grpcBadBodyError } - updatedOrg, err := v.OrgService.Update(ctx, modelv1.Organization{ + updatedOrg, err := v.OrgService.Update(ctx, model.Organization{ Id: request.GetId(), Name: request.GetBody().Name, Slug: request.GetBody().Slug, @@ -156,7 +156,7 @@ func (v Dep) UpdateOrganization(ctx context.Context, request *shieldv1.UpdateOrg return &shieldv1.UpdateOrganizationResponse{Organization: &orgPB}, nil } -func transformOrgToPB(org modelv1.Organization) (shieldv1.Organization, error) { +func transformOrgToPB(org model.Organization) (shieldv1.Organization, error) { metaData, err := structpb.NewStruct(mapOfInterfaceValues(org.Metadata)) if err != nil { return shieldv1.Organization{}, err diff --git a/api/handler/v1/org_test.go b/api/handler/v1/org_test.go index ae314cbf7..e778063c5 100644 --- a/api/handler/v1/org_test.go +++ b/api/handler/v1/org_test.go @@ -8,7 +8,7 @@ import ( "github.com/stretchr/testify/assert" - modelv1 "github.com/odpf/shield/model/v1" + "github.com/odpf/shield/model" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" @@ -18,7 +18,7 @@ import ( shieldv1 "go.buf.build/odpf/gw/odpf/proton/odpf/shield/v1" ) -var testOrgMap = map[string]modelv1.Organization{ +var testOrgMap = map[string]model.Organization{ "9f256f86-31a3-11ec-8d3d-0242ac130003": { Id: "9f256f86-31a3-11ec-8d3d-0242ac130003", Name: "Org 1", @@ -42,15 +42,15 @@ func TestListOrganizations(t *testing.T) { }{ { title: "error in Org Service", - mockOrgSrv: mockOrgSrv{ListOrganizationsFunc: func(ctx context.Context) (organizations []modelv1.Organization, err error) { - return []modelv1.Organization{}, errors.New("some error") + mockOrgSrv: mockOrgSrv{ListOrganizationsFunc: func(ctx context.Context) (organizations []model.Organization, err error) { + return []model.Organization{}, errors.New("some error") }}, want: nil, err: status.Errorf(codes.Internal, internalServerError.Error()), }, { title: "success", - mockOrgSrv: mockOrgSrv{ListOrganizationsFunc: func(ctx context.Context) (organizations []modelv1.Organization, err error) { - var testOrgList []modelv1.Organization + mockOrgSrv: mockOrgSrv{ListOrganizationsFunc: func(ctx context.Context) (organizations []model.Organization, err error) { + var testOrgList []model.Organization for _, o := range testOrgMap { testOrgList = append(testOrgList, o) } @@ -98,8 +98,8 @@ func TestCreateOrganization(t *testing.T) { }{ { title: "error in fetching org list", - mockOrgSrv: mockOrgSrv{CreateOrganizationFunc: func(ctx context.Context, o modelv1.Organization) (modelv1.Organization, error) { - return modelv1.Organization{}, errors.New("some error") + mockOrgSrv: mockOrgSrv{CreateOrganizationFunc: func(ctx context.Context, o model.Organization) (model.Organization, error) { + return model.Organization{}, errors.New("some error") }}, req: &shieldv1.CreateOrganizationRequest{Body: &shieldv1.OrganizationRequestBody{ Name: "some org", @@ -125,8 +125,8 @@ func TestCreateOrganization(t *testing.T) { }, { title: "success", - mockOrgSrv: mockOrgSrv{CreateOrganizationFunc: func(ctx context.Context, o modelv1.Organization) (modelv1.Organization, error) { - return modelv1.Organization{ + mockOrgSrv: mockOrgSrv{CreateOrganizationFunc: func(ctx context.Context, o model.Organization) (model.Organization, error) { + return model.Organization{ Id: "new-abc", Name: "some org", Slug: "abc", @@ -167,24 +167,24 @@ func TestCreateOrganization(t *testing.T) { } type mockOrgSrv struct { - GetOrganizationFunc func(ctx context.Context, id string) (modelv1.Organization, error) - CreateOrganizationFunc func(ctx context.Context, org modelv1.Organization) (modelv1.Organization, error) - ListOrganizationsFunc func(ctx context.Context) ([]modelv1.Organization, error) - UpdateOrganizationFunc func(ctx context.Context, toUpdate modelv1.Organization) (modelv1.Organization, error) + GetOrganizationFunc func(ctx context.Context, id string) (model.Organization, error) + CreateOrganizationFunc func(ctx context.Context, org model.Organization) (model.Organization, error) + ListOrganizationsFunc func(ctx context.Context) ([]model.Organization, error) + UpdateOrganizationFunc func(ctx context.Context, toUpdate model.Organization) (model.Organization, error) } -func (m mockOrgSrv) Get(ctx context.Context, id string) (modelv1.Organization, error) { +func (m mockOrgSrv) Get(ctx context.Context, id string) (model.Organization, error) { return m.GetOrganizationFunc(ctx, id) } -func (m mockOrgSrv) Create(ctx context.Context, org modelv1.Organization) (modelv1.Organization, error) { +func (m mockOrgSrv) Create(ctx context.Context, org model.Organization) (model.Organization, error) { return m.CreateOrganizationFunc(ctx, org) } -func (m mockOrgSrv) List(ctx context.Context) ([]modelv1.Organization, error) { +func (m mockOrgSrv) List(ctx context.Context) ([]model.Organization, error) { return m.ListOrganizationsFunc(ctx) } -func (m mockOrgSrv) Update(ctx context.Context, toUpdate modelv1.Organization) (modelv1.Organization, error) { +func (m mockOrgSrv) Update(ctx context.Context, toUpdate model.Organization) (model.Organization, error) { return m.UpdateOrganizationFunc(ctx, toUpdate) } diff --git a/api/handler/v1/project.go b/api/handler/v1/project.go index 259e3a6b9..19c20e446 100644 --- a/api/handler/v1/project.go +++ b/api/handler/v1/project.go @@ -8,7 +8,7 @@ import ( grpczap "github.com/grpc-ecosystem/go-grpc-middleware/logging/zap/ctxzap" "github.com/odpf/shield/internal/project" - modelv1 "github.com/odpf/shield/model/v1" + "github.com/odpf/shield/model" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" @@ -21,10 +21,10 @@ import ( var grpcProjectNotFoundErr = status.Errorf(codes.NotFound, "project doesn't exist") type ProjectService interface { - Get(ctx context.Context, id string) (modelv1.Project, error) - Create(ctx context.Context, project modelv1.Project) (modelv1.Project, error) - List(ctx context.Context) ([]modelv1.Project, error) - Update(ctx context.Context, toUpdate modelv1.Project) (modelv1.Project, error) + Get(ctx context.Context, id string) (model.Project, error) + Create(ctx context.Context, project model.Project) (model.Project, error) + List(ctx context.Context) ([]model.Project, error) + Update(ctx context.Context, toUpdate model.Project) (model.Project, error) } func (v Dep) ListProjects(ctx context.Context, request *shieldv1.ListProjectsRequest) (*shieldv1.ListProjectsResponse, error) { @@ -63,7 +63,7 @@ func (v Dep) CreateProject(ctx context.Context, request *shieldv1.CreateProjectR slug = generateSlug(request.GetBody().Name) } - newProject, err := v.ProjectService.Create(ctx, modelv1.Project{ + newProject, err := v.ProjectService.Create(ctx, model.Project{ Name: request.GetBody().Name, Slug: slug, Metadata: metaDataMap, @@ -124,7 +124,7 @@ func (v Dep) UpdateProject(ctx context.Context, request *shieldv1.UpdateProjectR return nil, grpcBadBodyError } - updatedProject, err := v.ProjectService.Update(ctx, modelv1.Project{ + updatedProject, err := v.ProjectService.Update(ctx, model.Project{ Id: request.GetId(), Name: request.GetBody().Name, Slug: request.GetBody().Slug, @@ -144,7 +144,7 @@ func (v Dep) UpdateProject(ctx context.Context, request *shieldv1.UpdateProjectR return &shieldv1.UpdateProjectResponse{Project: &projectPB}, nil } -func transformProjectToPB(prj modelv1.Project) (shieldv1.Project, error) { +func transformProjectToPB(prj model.Project) (shieldv1.Project, error) { metaData, err := structpb.NewStruct(mapOfInterfaceValues(prj.Metadata)) if err != nil { return shieldv1.Project{}, err diff --git a/api/handler/v1/project_test.go b/api/handler/v1/project_test.go index be0e26765..5a181d7c7 100644 --- a/api/handler/v1/project_test.go +++ b/api/handler/v1/project_test.go @@ -9,17 +9,17 @@ import ( "github.com/stretchr/testify/assert" "github.com/odpf/shield/internal/project" - modelv1 "github.com/odpf/shield/model/v1" - - shieldv1 "go.buf.build/odpf/gw/odpf/proton/odpf/shield/v1" + "github.com/odpf/shield/model" "google.golang.org/protobuf/types/known/structpb" "google.golang.org/protobuf/types/known/timestamppb" + + shieldv1 "go.buf.build/odpf/gw/odpf/proton/odpf/shield/v1" ) var testProjectID = "ab657ae7-8c9e-45eb-9862-dd9ceb6d5c71" -var testProjectMap = map[string]modelv1.Project{ +var testProjectMap = map[string]model.Project{ "ab657ae7-8c9e-45eb-9862-dd9ceb6d5c71": { Id: "ab657ae7-8c9e-45eb-9862-dd9ceb6d5c71", Name: "Prj 1", @@ -76,8 +76,8 @@ func TestCreateProject(t *testing.T) { }, }, }}, - mockProjectSrv: mockProject{CreateProjectFunc: func(ctx context.Context, prj modelv1.Project) (modelv1.Project, error) { - return modelv1.Project{}, errors.New("some service error") + mockProjectSrv: mockProject{CreateProjectFunc: func(ctx context.Context, prj model.Project) (model.Project, error) { + return model.Project{}, errors.New("some service error") }}, err: grpcInternalServerError, }, @@ -92,7 +92,7 @@ func TestCreateProject(t *testing.T) { }, }, }}, - mockProjectSrv: mockProject{CreateProjectFunc: func(ctx context.Context, prj modelv1.Project) (modelv1.Project, error) { + mockProjectSrv: mockProject{CreateProjectFunc: func(ctx context.Context, prj model.Project) (model.Project, error) { return testProjectMap[testProjectID], nil }}, want: &shieldv1.CreateProjectResponse{Project: &shieldv1.Project{ @@ -136,16 +136,16 @@ func TestListProjects(t *testing.T) { { title: "error in service", req: &shieldv1.ListProjectsRequest{}, - mockProjectSrv: mockProject{ListProjectFunc: func(ctx context.Context) ([]modelv1.Project, error) { - return []modelv1.Project{}, errors.New("some store error") + mockProjectSrv: mockProject{ListProjectFunc: func(ctx context.Context) ([]model.Project, error) { + return []model.Project{}, errors.New("some store error") }}, err: grpcInternalServerError, }, { title: "success", req: &shieldv1.ListProjectsRequest{}, - mockProjectSrv: mockProject{ListProjectFunc: func(ctx context.Context) ([]modelv1.Project, error) { - var prjs []modelv1.Project + mockProjectSrv: mockProject{ListProjectFunc: func(ctx context.Context) ([]model.Project, error) { + var prjs []model.Project for _, v := range testProjectMap { prjs = append(prjs, v) @@ -208,31 +208,31 @@ func TestGetProject(t *testing.T) { { title: "project doesnt exist", req: &shieldv1.GetProjectRequest{}, - mockProjectSrv: mockProject{GetProjectFunc: func(ctx context.Context, id string) (modelv1.Project, error) { - return modelv1.Project{}, project.ProjectDoesntExist + mockProjectSrv: mockProject{GetProjectFunc: func(ctx context.Context, id string) (model.Project, error) { + return model.Project{}, project.ProjectDoesntExist }}, err: grpcProjectNotFoundErr, }, { title: "uuid syntax error", req: &shieldv1.GetProjectRequest{}, - mockProjectSrv: mockProject{GetProjectFunc: func(ctx context.Context, id string) (modelv1.Project, error) { - return modelv1.Project{}, project.InvalidUUID + mockProjectSrv: mockProject{GetProjectFunc: func(ctx context.Context, id string) (model.Project, error) { + return model.Project{}, project.InvalidUUID }}, err: grpcBadBodyError, }, { title: "service error", req: &shieldv1.GetProjectRequest{}, - mockProjectSrv: mockProject{GetProjectFunc: func(ctx context.Context, id string) (modelv1.Project, error) { - return modelv1.Project{}, errors.New("some error") + mockProjectSrv: mockProject{GetProjectFunc: func(ctx context.Context, id string) (model.Project, error) { + return model.Project{}, errors.New("some error") }}, err: grpcInternalServerError, }, { title: "success", req: &shieldv1.GetProjectRequest{}, - mockProjectSrv: mockProject{GetProjectFunc: func(ctx context.Context, id string) (modelv1.Project, error) { + mockProjectSrv: mockProject{GetProjectFunc: func(ctx context.Context, id string) (model.Project, error) { return testProjectMap[testProjectID], nil }}, want: &shieldv1.GetProjectResponse{Project: &shieldv1.Project{ @@ -264,24 +264,24 @@ func TestGetProject(t *testing.T) { } type mockProject struct { - GetProjectFunc func(ctx context.Context, id string) (modelv1.Project, error) - CreateProjectFunc func(ctx context.Context, project modelv1.Project) (modelv1.Project, error) - ListProjectFunc func(ctx context.Context) ([]modelv1.Project, error) - UpdateProjectFunc func(ctx context.Context, toUpdate modelv1.Project) (modelv1.Project, error) + GetProjectFunc func(ctx context.Context, id string) (model.Project, error) + CreateProjectFunc func(ctx context.Context, project model.Project) (model.Project, error) + ListProjectFunc func(ctx context.Context) ([]model.Project, error) + UpdateProjectFunc func(ctx context.Context, toUpdate model.Project) (model.Project, error) } -func (m mockProject) List(ctx context.Context) ([]modelv1.Project, error) { +func (m mockProject) List(ctx context.Context) ([]model.Project, error) { return m.ListProjectFunc(ctx) } -func (m mockProject) Create(ctx context.Context, project modelv1.Project) (modelv1.Project, error) { +func (m mockProject) Create(ctx context.Context, project model.Project) (model.Project, error) { return m.CreateProjectFunc(ctx, project) } -func (m mockProject) Get(ctx context.Context, id string) (modelv1.Project, error) { +func (m mockProject) Get(ctx context.Context, id string) (model.Project, error) { return m.GetProjectFunc(ctx, id) } -func (m mockProject) Update(ctx context.Context, toUpdate modelv1.Project) (modelv1.Project, error) { +func (m mockProject) Update(ctx context.Context, toUpdate model.Project) (model.Project, error) { return m.UpdateProjectFunc(ctx, toUpdate) } diff --git a/internal/org/org.go b/internal/org/org.go index 1822e8c3c..82b24adcf 100644 --- a/internal/org/org.go +++ b/internal/org/org.go @@ -4,7 +4,7 @@ import ( "context" "errors" - modelv1 "github.com/odpf/shield/model/v1" + "github.com/odpf/shield/model" ) type Service struct { @@ -17,34 +17,34 @@ var ( ) type Store interface { - GetOrg(ctx context.Context, id string) (modelv1.Organization, error) - CreateOrg(ctx context.Context, org modelv1.Organization) (modelv1.Organization, error) - ListOrg(ctx context.Context) ([]modelv1.Organization, error) - UpdateOrg(ctx context.Context, toUpdate modelv1.Organization) (modelv1.Organization, error) + GetOrg(ctx context.Context, id string) (model.Organization, error) + CreateOrg(ctx context.Context, org model.Organization) (model.Organization, error) + ListOrg(ctx context.Context) ([]model.Organization, error) + UpdateOrg(ctx context.Context, toUpdate model.Organization) (model.Organization, error) } -func (s Service) Get(ctx context.Context, id string) (modelv1.Organization, error) { +func (s Service) Get(ctx context.Context, id string) (model.Organization, error) { return s.Store.GetOrg(ctx, id) } -func (s Service) Create(ctx context.Context, org modelv1.Organization) (modelv1.Organization, error) { - newOrg, err := s.Store.CreateOrg(ctx, modelv1.Organization{ +func (s Service) Create(ctx context.Context, org model.Organization) (model.Organization, error) { + newOrg, err := s.Store.CreateOrg(ctx, model.Organization{ Name: org.Name, Slug: org.Slug, Metadata: org.Metadata, }) if err != nil { - return modelv1.Organization{}, err + return model.Organization{}, err } return newOrg, nil } -func (s Service) List(ctx context.Context) ([]modelv1.Organization, error) { +func (s Service) List(ctx context.Context) ([]model.Organization, error) { return s.Store.ListOrg(ctx) } -func (s Service) Update(ctx context.Context, toUpdate modelv1.Organization) (modelv1.Organization, error) { +func (s Service) Update(ctx context.Context, toUpdate model.Organization) (model.Organization, error) { return s.Store.UpdateOrg(ctx, toUpdate) } diff --git a/internal/project/project.go b/internal/project/project.go index 416f97d85..46878da3c 100644 --- a/internal/project/project.go +++ b/internal/project/project.go @@ -4,7 +4,7 @@ import ( "context" "errors" - modelv1 "github.com/odpf/shield/model/v1" + "github.com/odpf/shield/model" ) type Service struct { @@ -17,18 +17,18 @@ var ( ) type Store interface { - GetProject(ctx context.Context, id string) (modelv1.Project, error) - CreateProject(ctx context.Context, org modelv1.Project) (modelv1.Project, error) - ListProject(ctx context.Context) ([]modelv1.Project, error) - UpdateProject(ctx context.Context, toUpdate modelv1.Project) (modelv1.Project, error) + GetProject(ctx context.Context, id string) (model.Project, error) + CreateProject(ctx context.Context, org model.Project) (model.Project, error) + ListProject(ctx context.Context) ([]model.Project, error) + UpdateProject(ctx context.Context, toUpdate model.Project) (model.Project, error) } -func (s Service) Get(ctx context.Context, id string) (modelv1.Project, error) { +func (s Service) Get(ctx context.Context, id string) (model.Project, error) { return s.Store.GetProject(ctx, id) } -func (s Service) Create(ctx context.Context, project modelv1.Project) (modelv1.Project, error) { - newOrg, err := s.Store.CreateProject(ctx, modelv1.Project{ +func (s Service) Create(ctx context.Context, project model.Project) (model.Project, error) { + newOrg, err := s.Store.CreateProject(ctx, model.Project{ Name: project.Name, Slug: project.Slug, Metadata: project.Metadata, @@ -36,16 +36,16 @@ func (s Service) Create(ctx context.Context, project modelv1.Project) (modelv1.P }) if err != nil { - return modelv1.Project{}, err + return model.Project{}, err } return newOrg, nil } -func (s Service) List(ctx context.Context) ([]modelv1.Project, error) { +func (s Service) List(ctx context.Context) ([]model.Project, error) { return s.Store.ListProject(ctx) } -func (s Service) Update(ctx context.Context, toUpdate modelv1.Project) (modelv1.Project, error) { +func (s Service) Update(ctx context.Context, toUpdate model.Project) (model.Project, error) { return s.Store.UpdateProject(ctx, toUpdate) } diff --git a/model/v1/v1.go b/model/model.go similarity index 96% rename from model/v1/v1.go rename to model/model.go index 290c2029a..2cc3b3c58 100644 --- a/model/v1/v1.go +++ b/model/model.go @@ -1,4 +1,4 @@ -package v1 +package model import "time" diff --git a/store/postgres/org.go b/store/postgres/org.go index 9c3b54c17..98db0fa3b 100644 --- a/store/postgres/org.go +++ b/store/postgres/org.go @@ -8,10 +8,10 @@ import ( "fmt" "time" - "github.com/odpf/shield/internal/org" - modelv1 "github.com/odpf/shield/model/v1" - "github.com/jmoiron/sqlx" + + "github.com/odpf/shield/internal/org" + "github.com/odpf/shield/model" ) type Organization struct { @@ -32,12 +32,12 @@ const ( updateOrganizationQuery = `UPDATE organizations set name = $2, slug = $3, metadata = $4, updated_at = now() where id = $1 RETURNING id, name, slug, metadata, created_at, updated_at;` ) -func (s Store) GetOrg(ctx context.Context, id string) (modelv1.Organization, error) { +func (s Store) GetOrg(ctx context.Context, id string) (model.Organization, error) { fetchedOrg, _, err := s.selectOrg(ctx, id, false, nil) return fetchedOrg, err } -func (s Store) selectOrg(ctx context.Context, id string, forUpdate bool, txn *sqlx.Tx) (modelv1.Organization, int, error) { +func (s Store) selectOrg(ctx context.Context, id string, forUpdate bool, txn *sqlx.Tx) (model.Organization, int, error) { var fetchedOrg Organization err := s.DB.WithTimeout(ctx, func(ctx context.Context) error { @@ -49,27 +49,27 @@ func (s Store) selectOrg(ctx context.Context, id string, forUpdate bool, txn *sq }) if errors.Is(err, sql.ErrNoRows) { - return modelv1.Organization{}, -1, org.OrgDoesntExist + return model.Organization{}, -1, org.OrgDoesntExist } else if err != nil && fmt.Sprintf("%s", err.Error()[0:38]) == "pq: invalid input syntax for type uuid" { // TODO: this uuid syntax is a error defined in db, not in library // need to look into better ways to implement this - return modelv1.Organization{}, -1, org.InvalidUUID + return model.Organization{}, -1, org.InvalidUUID } else if err != nil { - return modelv1.Organization{}, -1, fmt.Errorf("%w: %s", dbErr, err) + return model.Organization{}, -1, fmt.Errorf("%w: %s", dbErr, err) } transformedOrg, err := transformToOrg(fetchedOrg) if err != nil { - return modelv1.Organization{}, -1, fmt.Errorf("%w: %s", parseErr, err) + return model.Organization{}, -1, fmt.Errorf("%w: %s", parseErr, err) } return transformedOrg, fetchedOrg.Version, nil } -func (s Store) CreateOrg(ctx context.Context, orgToCreate modelv1.Organization) (modelv1.Organization, error) { +func (s Store) CreateOrg(ctx context.Context, orgToCreate model.Organization) (model.Organization, error) { marshaledMetadata, err := json.Marshal(orgToCreate.Metadata) if err != nil { - return modelv1.Organization{}, fmt.Errorf("%w: %s", parseErr, err) + return model.Organization{}, fmt.Errorf("%w: %s", parseErr, err) } var newOrg Organization @@ -78,37 +78,37 @@ func (s Store) CreateOrg(ctx context.Context, orgToCreate modelv1.Organization) }) if err != nil { - return modelv1.Organization{}, fmt.Errorf("%w: %s", dbErr, err) + return model.Organization{}, fmt.Errorf("%w: %s", dbErr, err) } transformedOrg, err := transformToOrg(newOrg) if err != nil { - return modelv1.Organization{}, fmt.Errorf("%w: %s", parseErr, err) + return model.Organization{}, fmt.Errorf("%w: %s", parseErr, err) } return transformedOrg, nil } -func (s Store) ListOrg(ctx context.Context) ([]modelv1.Organization, error) { +func (s Store) ListOrg(ctx context.Context) ([]model.Organization, error) { var fetchedOrgs []Organization err := s.DB.WithTimeout(ctx, func(ctx context.Context) error { return s.DB.SelectContext(ctx, &fetchedOrgs, listOrganizationsQuery) }) if errors.Is(err, sql.ErrNoRows) { - return []modelv1.Organization{}, org.OrgDoesntExist + return []model.Organization{}, org.OrgDoesntExist } if err != nil { - return []modelv1.Organization{}, fmt.Errorf("%w: %s", dbErr, err) + return []model.Organization{}, fmt.Errorf("%w: %s", dbErr, err) } - var transformedOrgs []modelv1.Organization + var transformedOrgs []model.Organization for _, o := range fetchedOrgs { transformedOrg, err := transformToOrg(o) if err != nil { - return []modelv1.Organization{}, fmt.Errorf("%w: %s", parseErr, err) + return []model.Organization{}, fmt.Errorf("%w: %s", parseErr, err) } transformedOrgs = append(transformedOrgs, transformedOrg) @@ -117,12 +117,12 @@ func (s Store) ListOrg(ctx context.Context) ([]modelv1.Organization, error) { return transformedOrgs, nil } -func (s Store) UpdateOrg(ctx context.Context, toUpdate modelv1.Organization) (modelv1.Organization, error) { +func (s Store) UpdateOrg(ctx context.Context, toUpdate model.Organization) (model.Organization, error) { var updatedOrg Organization marshaledMetadata, err := json.Marshal(toUpdate.Metadata) if err != nil { - return modelv1.Organization{}, fmt.Errorf("%w: %s", parseErr, err) + return model.Organization{}, fmt.Errorf("%w: %s", parseErr, err) } err = s.DB.WithTimeout(ctx, func(ctx context.Context) error { @@ -130,24 +130,24 @@ func (s Store) UpdateOrg(ctx context.Context, toUpdate modelv1.Organization) (mo }) if err != nil { - return modelv1.Organization{}, fmt.Errorf("%s: %w", txnErr, err) + return model.Organization{}, fmt.Errorf("%s: %w", txnErr, err) } toUpdate, err = transformToOrg(updatedOrg) if err != nil { - return modelv1.Organization{}, fmt.Errorf("%s: %w", parseErr, err) + return model.Organization{}, fmt.Errorf("%s: %w", parseErr, err) } return toUpdate, nil } -func transformToOrg(from Organization) (modelv1.Organization, error) { +func transformToOrg(from Organization) (model.Organization, error) { var unmarshalledMetadata map[string]string if err := json.Unmarshal(from.Metadata, &unmarshalledMetadata); err != nil { - return modelv1.Organization{}, err + return model.Organization{}, err } - return modelv1.Organization{ + return model.Organization{ Id: from.Id, Name: from.Name, Slug: from.Slug, diff --git a/store/postgres/projects.go b/store/postgres/projects.go index a9cba8934..ac655d778 100644 --- a/store/postgres/projects.go +++ b/store/postgres/projects.go @@ -9,8 +9,7 @@ import ( "time" "github.com/odpf/shield/internal/project" - - modelv1 "github.com/odpf/shield/model/v1" + "github.com/odpf/shield/model" ) type Project struct { @@ -30,38 +29,38 @@ const ( updateProjectQuery = `UPDATE projects set name = $2, slug = $3, org_id=$4, metadata = $5, updated_at = now() where id = $1 RETURNING id, name, slug, metadata, created_at, updated_at;` ) -func (s Store) GetProject(ctx context.Context, id string) (modelv1.Project, error) { +func (s Store) GetProject(ctx context.Context, id string) (model.Project, error) { var fetchedProject Project err := s.DB.WithTimeout(ctx, func(ctx context.Context) error { return s.DB.GetContext(ctx, &fetchedProject, getProjectsQuery, id) }) if errors.Is(err, sql.ErrNoRows) { - return modelv1.Project{}, project.ProjectDoesntExist + return model.Project{}, project.ProjectDoesntExist } else if err != nil && fmt.Sprintf("%s", err.Error()[0:38]) == "pq: invalid input syntax for type uuid" { // TODO: this uuid syntax is a error defined in db, not in library // need to look into better ways to implement this - return modelv1.Project{}, project.InvalidUUID + return model.Project{}, project.InvalidUUID } else if err != nil { - return modelv1.Project{}, fmt.Errorf("%w: %s", dbErr, err) + return model.Project{}, fmt.Errorf("%w: %s", dbErr, err) } if err != nil { - return modelv1.Project{}, err + return model.Project{}, err } transformedProject, err := transformToProject(fetchedProject) if err != nil { - return modelv1.Project{}, err + return model.Project{}, err } return transformedProject, nil } -func (s Store) CreateProject(ctx context.Context, projectToCreate modelv1.Project) (modelv1.Project, error) { +func (s Store) CreateProject(ctx context.Context, projectToCreate model.Project) (model.Project, error) { marshaledMetadata, err := json.Marshal(projectToCreate.Metadata) if err != nil { - return modelv1.Project{}, fmt.Errorf("%w: %s", parseErr, err) + return model.Project{}, fmt.Errorf("%w: %s", parseErr, err) } var newProject Project @@ -70,37 +69,37 @@ func (s Store) CreateProject(ctx context.Context, projectToCreate modelv1.Projec }) if err != nil { - return modelv1.Project{}, fmt.Errorf("%w: %s", dbErr, err) + return model.Project{}, fmt.Errorf("%w: %s", dbErr, err) } transformedOrg, err := transformToProject(newProject) if err != nil { - return modelv1.Project{}, fmt.Errorf("%w: %s", parseErr, err) + return model.Project{}, fmt.Errorf("%w: %s", parseErr, err) } return transformedOrg, nil } -func (s Store) ListProject(ctx context.Context) ([]modelv1.Project, error) { +func (s Store) ListProject(ctx context.Context) ([]model.Project, error) { var fetchedProjects []Project err := s.DB.WithTimeout(ctx, func(ctx context.Context) error { return s.DB.SelectContext(ctx, &fetchedProjects, listProjectQuery) }) if errors.Is(err, sql.ErrNoRows) { - return []modelv1.Project{}, project.ProjectDoesntExist + return []model.Project{}, project.ProjectDoesntExist } if err != nil { - return []modelv1.Project{}, fmt.Errorf("%w: %s", dbErr, err) + return []model.Project{}, fmt.Errorf("%w: %s", dbErr, err) } - var transformedProjects []modelv1.Project + var transformedProjects []model.Project for _, o := range fetchedProjects { transformedOrg, err := transformToProject(o) if err != nil { - return []modelv1.Project{}, fmt.Errorf("%w: %s", parseErr, err) + return []model.Project{}, fmt.Errorf("%w: %s", parseErr, err) } transformedProjects = append(transformedProjects, transformedOrg) @@ -109,12 +108,12 @@ func (s Store) ListProject(ctx context.Context) ([]modelv1.Project, error) { return transformedProjects, nil } -func (s Store) UpdateProject(ctx context.Context, toUpdate modelv1.Project) (modelv1.Project, error) { +func (s Store) UpdateProject(ctx context.Context, toUpdate model.Project) (model.Project, error) { var updatedProject Project marshaledMetadata, err := json.Marshal(toUpdate.Metadata) if err != nil { - return modelv1.Project{}, fmt.Errorf("%w: %s", parseErr, err) + return model.Project{}, fmt.Errorf("%w: %s", parseErr, err) } err = s.DB.WithTimeout(ctx, func(ctx context.Context) error { @@ -122,30 +121,30 @@ func (s Store) UpdateProject(ctx context.Context, toUpdate modelv1.Project) (mod }) if errors.Is(err, sql.ErrNoRows) { - return modelv1.Project{}, project.ProjectDoesntExist + return model.Project{}, project.ProjectDoesntExist } else if err != nil && fmt.Sprintf("%s", err.Error()[0:38]) == "pq: invalid input syntax for type uuid" { // TODO: this uuid syntax is a error defined in db, not in library // need to look into better ways to implement this - return modelv1.Project{}, fmt.Errorf("%w: %s", project.InvalidUUID, err) + return model.Project{}, fmt.Errorf("%w: %s", project.InvalidUUID, err) } else if err != nil { - return modelv1.Project{}, fmt.Errorf("%w: %s", dbErr, err) + return model.Project{}, fmt.Errorf("%w: %s", dbErr, err) } toUpdate, err = transformToProject(updatedProject) if err != nil { - return modelv1.Project{}, fmt.Errorf("%s: %w", parseErr, err) + return model.Project{}, fmt.Errorf("%s: %w", parseErr, err) } return toUpdate, nil } -func transformToProject(from Project) (modelv1.Project, error) { +func transformToProject(from Project) (model.Project, error) { var unmarshalledMetadata map[string]string if err := json.Unmarshal(from.Metadata, &unmarshalledMetadata); err != nil { - return modelv1.Project{}, err + return model.Project{}, err } - return modelv1.Project{ + return model.Project{ Id: from.Id, Name: from.Name, Slug: from.Slug, From f311a636648eeee38aecf0d44eaa79639843738e Mon Sep 17 00:00:00 2001 From: Kartik Verma Date: Thu, 11 Nov 2021 16:55:32 +0530 Subject: [PATCH 10/12] fix: remove versioning from org table --- ...020192111_create_organization_table.up.sql | 1 - store/postgres/org.go | 28 ++++++------------- 2 files changed, 8 insertions(+), 21 deletions(-) diff --git a/store/postgres/migrations/20211020192111_create_organization_table.up.sql b/store/postgres/migrations/20211020192111_create_organization_table.up.sql index 20d40079d..0c7b77665 100644 --- a/store/postgres/migrations/20211020192111_create_organization_table.up.sql +++ b/store/postgres/migrations/20211020192111_create_organization_table.up.sql @@ -4,7 +4,6 @@ CREATE TABLE IF NOT EXISTS organizations name varchar UNIQUE NOT NULL, slug varchar UNIQUE NOT NULL, metadata jsonb, - version int NOT NULL DEFAULT 0, created_at timestamptz NOT NULL DEFAULT NOW(), updated_at timestamptz NOT NULL DEFAULT NOW(), deleted_at timestamptz diff --git a/store/postgres/org.go b/store/postgres/org.go index 98db0fa3b..aed5aa462 100644 --- a/store/postgres/org.go +++ b/store/postgres/org.go @@ -8,8 +8,6 @@ import ( "fmt" "time" - "github.com/jmoiron/sqlx" - "github.com/odpf/shield/internal/org" "github.com/odpf/shield/model" ) @@ -19,7 +17,6 @@ type Organization struct { Name string `db:"name"` Slug string `db:"slug"` Metadata []byte `db:"metadata"` - Version int `db:"version"` CreatedAt time.Time `db:"created_at"` UpdatedAt time.Time `db:"updated_at"` } @@ -28,42 +25,33 @@ const ( getOrganizationsQuery = `SELECT id, name, slug, metadata, created_at, updated_at from organizations where id=$1;` createOrganizationQuery = `INSERT INTO organizations(name, slug, metadata) values($1, $2, $3) RETURNING id, name, slug, metadata, created_at, updated_at;` listOrganizationsQuery = `SELECT id, name, slug, metadata, created_at, updated_at from organizations;` - selectOrganizationForUpdateQuery = `SELECT id, name, slug, metadata, version, updated_at from organizations where id=$1;` updateOrganizationQuery = `UPDATE organizations set name = $2, slug = $3, metadata = $4, updated_at = now() where id = $1 RETURNING id, name, slug, metadata, created_at, updated_at;` ) func (s Store) GetOrg(ctx context.Context, id string) (model.Organization, error) { - fetchedOrg, _, err := s.selectOrg(ctx, id, false, nil) - return fetchedOrg, err -} - -func (s Store) selectOrg(ctx context.Context, id string, forUpdate bool, txn *sqlx.Tx) (model.Organization, int, error) { var fetchedOrg Organization - + //fetchedOrg, _, err := s.selectOrg(ctx, id, false, nil) + //return fetchedOrg, err err := s.DB.WithTimeout(ctx, func(ctx context.Context) error { - if forUpdate { - return txn.GetContext(ctx, &fetchedOrg, selectOrganizationForUpdateQuery, id) - } else { - return s.DB.GetContext(ctx, &fetchedOrg, getOrganizationsQuery, id) - } + return s.DB.GetContext(ctx, &fetchedOrg, getOrganizationsQuery, id) }) if errors.Is(err, sql.ErrNoRows) { - return model.Organization{}, -1, org.OrgDoesntExist + return model.Organization{}, org.OrgDoesntExist } else if err != nil && fmt.Sprintf("%s", err.Error()[0:38]) == "pq: invalid input syntax for type uuid" { // TODO: this uuid syntax is a error defined in db, not in library // need to look into better ways to implement this - return model.Organization{}, -1, org.InvalidUUID + return model.Organization{}, org.InvalidUUID } else if err != nil { - return model.Organization{}, -1, fmt.Errorf("%w: %s", dbErr, err) + return model.Organization{}, fmt.Errorf("%w: %s", dbErr, err) } transformedOrg, err := transformToOrg(fetchedOrg) if err != nil { - return model.Organization{}, -1, fmt.Errorf("%w: %s", parseErr, err) + return model.Organization{}, fmt.Errorf("%w: %s", parseErr, err) } - return transformedOrg, fetchedOrg.Version, nil + return transformedOrg, nil } func (s Store) CreateOrg(ctx context.Context, orgToCreate model.Organization) (model.Organization, error) { From 1d56fa7f2512d566526d5f109e91c8e1421adecd Mon Sep 17 00:00:00 2001 From: Kartik Verma Date: Thu, 11 Nov 2021 16:57:36 +0530 Subject: [PATCH 11/12] fix: format correction --- store/postgres/org.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/store/postgres/org.go b/store/postgres/org.go index aed5aa462..322845aa1 100644 --- a/store/postgres/org.go +++ b/store/postgres/org.go @@ -22,10 +22,10 @@ type Organization struct { } const ( - getOrganizationsQuery = `SELECT id, name, slug, metadata, created_at, updated_at from organizations where id=$1;` - createOrganizationQuery = `INSERT INTO organizations(name, slug, metadata) values($1, $2, $3) RETURNING id, name, slug, metadata, created_at, updated_at;` - listOrganizationsQuery = `SELECT id, name, slug, metadata, created_at, updated_at from organizations;` - updateOrganizationQuery = `UPDATE organizations set name = $2, slug = $3, metadata = $4, updated_at = now() where id = $1 RETURNING id, name, slug, metadata, created_at, updated_at;` + getOrganizationsQuery = `SELECT id, name, slug, metadata, created_at, updated_at from organizations where id=$1;` + createOrganizationQuery = `INSERT INTO organizations(name, slug, metadata) values($1, $2, $3) RETURNING id, name, slug, metadata, created_at, updated_at;` + listOrganizationsQuery = `SELECT id, name, slug, metadata, created_at, updated_at from organizations;` + updateOrganizationQuery = `UPDATE organizations set name = $2, slug = $3, metadata = $4, updated_at = now() where id = $1 RETURNING id, name, slug, metadata, created_at, updated_at;` ) func (s Store) GetOrg(ctx context.Context, id string) (model.Organization, error) { From 436dd1acb4d3c098357b59be54850e60f7c5f88e Mon Sep 17 00:00:00 2001 From: Kartik Verma Date: Thu, 11 Nov 2021 16:58:42 +0530 Subject: [PATCH 12/12] fix: remove comments --- store/postgres/org.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/store/postgres/org.go b/store/postgres/org.go index 322845aa1..a7cc52248 100644 --- a/store/postgres/org.go +++ b/store/postgres/org.go @@ -30,8 +30,6 @@ const ( func (s Store) GetOrg(ctx context.Context, id string) (model.Organization, error) { var fetchedOrg Organization - //fetchedOrg, _, err := s.selectOrg(ctx, id, false, nil) - //return fetchedOrg, err err := s.DB.WithTimeout(ctx, func(ctx context.Context) error { return s.DB.GetContext(ctx, &fetchedOrg, getOrganizationsQuery, id) })