Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Split Repository Based On Entities #104

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion main.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ func main() {
log.SetLevel(logLevel)

log.Info("Pinging DB...")
err = repository.GetDB().Ping()
err = repository.Ping()
if err != nil {
log.Fatalf("DB ping failed: %s", err)
}
Expand Down
40 changes: 4 additions & 36 deletions repository/db.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,45 +2,13 @@ package repository

import (
"clamp-core/config"
"clamp-core/models"

"github.com/google/uuid"
"fmt"
)

// DBInterface provides a collection of method signatures that needs to be implemented for a specific database.
type DBInterface interface {
SaveServiceRequest(*models.ServiceRequest) (*models.ServiceRequest, error)
FindServiceRequestByID(uuid.UUID) (*models.ServiceRequest, error)
SaveWorkflow(*models.Workflow) (*models.Workflow, error)
FindWorkflowByName(string) (*models.Workflow, error)
SaveStepStatus(*models.StepsStatus) (*models.StepsStatus, error)
FindStepStatusByServiceRequestID(serviceRequestID uuid.UUID) ([]*models.StepsStatus, error)
FindStepStatusByServiceRequestIDAndStatus(serviceRequestID uuid.UUID, status models.Status) ([]*models.StepsStatus, error)
FindStepStatusByServiceRequestIDAndStepIDAndStatus(
serviceRequestID uuid.UUID, stepID int, status models.Status) (*models.StepsStatus, error)
FindAllStepStatusByServiceRequestIDAndStepID(serviceRequestID uuid.UUID, stepID int) ([]*models.StepsStatus, error)
GetWorkflows(pageNumber int, pageSize int, sortBy models.SortByFields) ([]*models.Workflow, int, error)
FindServiceRequestsByWorkflowName(workflowName string, pageNumber int, pageSize int) ([]*models.ServiceRequest, error)
DeleteWorkflowByName(string) error
Ping() error
}

var db DBInterface

func init() {
func Ping() error {
switch config.ENV.DBDriver {
case "postgres":
db = &postgres{}
return pgDB.Ping()
}
}

// GetDB returns the initialized database implementations. Currently only postgres is implemented.
func GetDB() DBInterface {
return db
}

// SetDB is used to update the db object with custom implementations.
// It is used in tests to override the actual db implementations with mock implementations
func SetDB(dbImpl DBInterface) {
db = dbImpl
return fmt.Errorf("Unsupported Database %s", config.ENV.DBDriver)
}
154 changes: 11 additions & 143 deletions repository/postgres.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,15 @@ package repository

import (
"clamp-core/config"
"clamp-core/models"
"context"
"errors"
"strings"
"sync"

"github.com/go-pg/pg/v9"
"github.com/google/uuid"

log "github.com/sirupsen/logrus"
)

// reference human readable keys to DB key values
var keyReferences = map[string]string{"id": "id", "created_at": "created_at", "name": "name"}

var singletonOnce sync.Once

type dbLogger struct{}
Expand Down Expand Up @@ -65,156 +59,30 @@ func GetPostgresOptions() *pg.Options {
}
}

type postgres struct {
type postgresDB struct {
db *pg.DB
}

func (p *postgres) FindServiceRequestsByWorkflowName(workflowName string, pageNumber int, pageSize int) ([]*models.ServiceRequest, error) {
var pgServiceRequests []models.PGServiceRequest
err := p.getDB().Model(&pgServiceRequests).
Where("workflow_name = ?", workflowName).
Offset(pageSize * pageNumber).
Limit(pageSize).
Select()
var workflows []*models.ServiceRequest
if err == nil {
for _, pgServiceRequest := range pgServiceRequests {
workflows = append(workflows, pgServiceRequest.ToServiceRequest())
}
}
return workflows, err
}

func (p *postgres) FindAllStepStatusByServiceRequestIDAndStepID(serviceRequestID uuid.UUID, stepID int) ([]*models.StepsStatus, error) {
var pgStepStatus []models.PGStepStatus
err := p.getDB().Model(&pgStepStatus).Where("service_request_id = ? and step_id = ?", serviceRequestID, stepID).Select()
var stepStatuses []*models.StepsStatus
if err == nil {
for i := range pgStepStatus {
stepStatuses = append(stepStatuses, pgStepStatus[i].ToStepStatus())
}
}
return stepStatuses, err
}

func (p *postgres) FindStepStatusByServiceRequestIDAndStepIDAndStatus(
serviceRequestID uuid.UUID, stepID int, status models.Status) (*models.StepsStatus, error) {
var pgStepStatus models.PGStepStatus
var stepStatuses models.StepsStatus
err := p.getDB().Model(&pgStepStatus).Where("service_request_id = ? and step_id = ? and status = ?",
serviceRequestID, stepID, status).Select()
if err != nil {
return &stepStatuses, err
}
return pgStepStatus.ToStepStatus(), err
}

func (p *postgres) FindStepStatusByServiceRequestIDAndStatus(
serviceRequestID uuid.UUID, status models.Status) ([]*models.StepsStatus, error) {
var pgStepStatus []models.PGStepStatus
var stepStatuses []*models.StepsStatus
err := p.getDB().Model(&pgStepStatus).Where("service_request_id = ? and status = ?", serviceRequestID, status).
Order("created_at ASC").Select()
if err != nil {
return stepStatuses, err
}
for i := range pgStepStatus {
stepStatuses = append(stepStatuses, pgStepStatus[i].ToStepStatus())
}
return stepStatuses, err
}

func (p *postgres) FindStepStatusByServiceRequestID(serviceRequestID uuid.UUID) ([]*models.StepsStatus, error) {
var pgStepStatus []models.PGStepStatus
err := p.getDB().Model(&pgStepStatus).Where("service_request_id = ?", serviceRequestID).Order("created_at ASC").Select()
var stepStatuses []*models.StepsStatus
if err == nil {
for i := range pgStepStatus {
stepStatuses = append(stepStatuses, pgStepStatus[i].ToStepStatus())
}
}
return stepStatuses, err
}

func (p *postgres) SaveStepStatus(stepStatus *models.StepsStatus) (*models.StepsStatus, error) {
pgStepStatusReq := stepStatus.ToPgStepStatus()
err := p.getDB().Insert(pgStepStatusReq)
return pgStepStatusReq.ToStepStatus(), err
}

func (p *postgres) FindWorkflowByName(workflowName string) (*models.Workflow, error) {
pgWorkflow := new(models.PGWorkflow)
err := p.getDB().Model(pgWorkflow).Where("name = ?", workflowName).Select()
return pgWorkflow.ToWorkflow(), err
}

func (p *postgres) DeleteWorkflowByName(workflowName string) error {
_, err := p.getDB().Model((*models.PGWorkflow)(nil)).Where("name = ?", workflowName).Delete()
return err
}

func (p *postgres) SaveWorkflow(workflowReq *models.Workflow) (*models.Workflow, error) {
pgWorkflow := workflowReq.ToPGWorkflow()
log.Debugf("pgworfklow: %v", pgWorkflow)
err := p.getDB().Insert(pgWorkflow)
return pgWorkflow.ToWorkflow(), err
}

func (p *postgres) FindServiceRequestByID(serviceRequestID uuid.UUID) (*models.ServiceRequest, error) {
pgServiceRequest := &models.PGServiceRequest{ID: serviceRequestID}
err := p.getDB().Select(pgServiceRequest)
if err != nil {
panic(err)
}
return pgServiceRequest.ToServiceRequest(), err
}

func (p *postgres) SaveServiceRequest(serviceReq *models.ServiceRequest) (*models.ServiceRequest, error) {
pgServReq := serviceReq.ToPgServiceRequest()
db := p.getDB()
err := db.Insert(pgServReq)
return pgServReq.ToServiceRequest(), err
}
var pgDB postgresDB

func (p *postgres) GetWorkflows(pageNumber int, pageSize int, sortFields models.SortByFields) ([]*models.Workflow, int, error) {
var pgWorkflows []models.PGWorkflow
query := p.getDB().Model(&pgWorkflows)
for _, sortField := range sortFields {
reference, found := keyReferences[sortField.Key]
if !found {
return []*models.Workflow{}, 0, errors.New("undefined key reference used")
}
order := sortField.Order
if found {
query = query.Order(reference + " " + order)
}
}
totalWorkflowsCount, err := query.Offset(pageSize * (pageNumber - 1)).
Limit(pageSize).SelectAndCount()
if err != nil {
return []*models.Workflow{}, 0, err
}
var workflows []*models.Workflow
for i := range pgWorkflows {
workflows = append(workflows, pgWorkflows[i].ToWorkflow())
}
return workflows, totalWorkflowsCount, err
func init() {
pgDB = postgresDB{}
}

func (p *postgres) Ping() error {
_, err := p.getDB().Exec("SELECT 1")
return err
}

func (p *postgres) getDB() *pg.DB {
func (p *postgresDB) GetDB() *pg.DB {
singletonOnce.Do(func() {
log.Info("Connecting to DB")
p.db = connectDB()
})
return p.db
}

func (p *postgres) closeDB() {
func (p *postgresDB) Ping() error {
_, err := p.GetDB().Exec("SELECT 1")
return err
}

func (p *postgresDB) closeDB() {
if p.db != nil {
log.Info("Disconnecting from DB")
p.db.Close()
Expand Down
35 changes: 35 additions & 0 deletions repository/service_request_repository.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package repository
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you can name the file as just service_request.go. the word repository is already part of the package name.


import (
"clamp-core/config"
"clamp-core/models"

"github.com/google/uuid"
)

// DBInterface provides a collection of method signatures that needs to be implemented for a specific database.
type ServiceRequestRepository interface {
SaveServiceRequest(*models.ServiceRequest) (*models.ServiceRequest, error)
FindServiceRequestByID(uuid.UUID) (*models.ServiceRequest, error)
FindServiceRequestsByWorkflowName(workflowName string, pageNumber int, pageSize int) ([]*models.ServiceRequest, error)
}

var serviceRequestRepository ServiceRequestRepository

func init() {
switch config.ENV.DBDriver {
case "postgres":
serviceRequestRepository = &servicerequestrepositorypostgres{}
}
}

// GetDB returns the initialized database implementations. Currently only postgres is implemented.
func GetServiceRequestRepository() ServiceRequestRepository {
return serviceRequestRepository
}

// SetDB is used to update the db object with custom implementations.
// It is used in tests to override the actual db implementations with mock implementations
func SetServiceRequestRepository(serviceRequestRepositoryImpl ServiceRequestRepository) {
serviceRequestRepository = serviceRequestRepositoryImpl
}
45 changes: 45 additions & 0 deletions repository/service_request_repository_postgres.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package repository

import (
"clamp-core/models"

"github.com/google/uuid"
"github.com/prometheus/common/log"
)

type servicerequestrepositorypostgres struct {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you can move postgres specific implementation to under postgres subpackage and name the struct as ServiceRequestRepository. So, in the above init function we will have serviceRequestRepository = postgres.ServiceRequestRepository

}

func (servicerequestrepository *servicerequestrepositorypostgres) SaveServiceRequest(serviceReq *models.ServiceRequest) (*models.ServiceRequest, error) {
pgServReq := serviceReq.ToPgServiceRequest()
db := pgDB.GetDB()
err := db.Insert(pgServReq)
return pgServReq.ToServiceRequest(), err
}

func (servicerequestrepository *servicerequestrepositorypostgres) FindServiceRequestsByWorkflowName(workflowName string, pageNumber int, pageSize int) ([]*models.ServiceRequest, error) {
var pgServiceRequests []models.PGServiceRequest
err := pgDB.GetDB().Model(&pgServiceRequests).
Where("WORKFLOW_NAME = ?", workflowName).
Offset(pageSize * pageNumber).
Limit(pageSize).
Select()
var workflows []*models.ServiceRequest
log.Info("workflow name %s %v", workflowName, pgServiceRequests)

if err == nil {
for _, pgServiceRequest := range pgServiceRequests {
workflows = append(workflows, pgServiceRequest.ToServiceRequest())
}
}
return workflows, err
}

func (servicerequestrepository *servicerequestrepositorypostgres) FindServiceRequestByID(serviceRequestID uuid.UUID) (*models.ServiceRequest, error) {
pgServiceRequest := &models.PGServiceRequest{ID: serviceRequestID}
err := pgDB.GetDB().Select(pgServiceRequest)
if err != nil {
panic(err)
}
return pgServiceRequest.ToServiceRequest(), err
}
38 changes: 38 additions & 0 deletions repository/step_status_repository.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package repository

import (
"clamp-core/config"
"clamp-core/models"

"github.com/google/uuid"
)

// DBInterface provides a collection of method signatures that needs to be implemented for a specific database.
type StepStatusRepository interface {
SaveStepStatus(*models.StepsStatus) (*models.StepsStatus, error)
FindStepStatusByServiceRequestID(serviceRequestID uuid.UUID) ([]*models.StepsStatus, error)
FindStepStatusByServiceRequestIDAndStatus(serviceRequestID uuid.UUID, status models.Status) ([]*models.StepsStatus, error)
FindStepStatusByServiceRequestIDAndStepIDAndStatus(
serviceRequestID uuid.UUID, stepID int, status models.Status) (*models.StepsStatus, error)
FindAllStepStatusByServiceRequestIDAndStepID(serviceRequestID uuid.UUID, stepID int) ([]*models.StepsStatus, error)
}

var stepStatusRepository StepStatusRepository

func init() {
switch config.ENV.DBDriver {
case "postgres":
stepStatusRepository = &stepstatusrepositorypostgres{}
}
}

// GetDB returns the initialized database implementations. Currently only postgres is implemented.
func GetStepStatusRepository() StepStatusRepository {
return stepStatusRepository
}

// SetDB is used to update the db object with custom implementations.
// It is used in tests to override the actual db implementations with mock implementations
func SetStepStatusRepository(stepStatusRepository StepStatusRepository) {
stepStatusRepository = stepStatusRepository
}
Loading