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

[EASI-3208] Update named statements to defer closure #672

Merged
merged 14 commits into from
Sep 11, 2023
Merged
Show file tree
Hide file tree
Changes from 2 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
8 changes: 4 additions & 4 deletions pkg/storage/access_controlStore.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ func (s *Store) CheckIfCollaborator(logger *zap.Logger, principalID uuid.UUID, m

isCollaborator := false

stmt, err := s.db.PrepareNamed(checkIfCollaboratorSQL)
stmt, err := s.statements.Get(checkIfCollaboratorSQL)
if err != nil {
return isCollaborator, err
}
Expand All @@ -46,7 +46,7 @@ func (s *Store) CheckIfCollaboratorByDiscussionID(logger *zap.Logger, principalI

isCollaborator := false

stmt, err := s.db.PrepareNamed(checkIfCollaboratorDiscussionIDSQL)
stmt, err := s.statements.Get(checkIfCollaboratorDiscussionIDSQL)
if err != nil {
return isCollaborator, err
}
Expand All @@ -73,7 +73,7 @@ func (s *Store) CheckIfCollaboratorBySolutionID(

isCollaborator := false

stmt, err := s.db.PrepareNamed(checkIfCollaboratorBySolutionIDSQL)
stmt, err := s.statements.Get(checkIfCollaboratorBySolutionIDSQL)
if err != nil {
return isCollaborator, err
}
Expand All @@ -100,7 +100,7 @@ func (s *Store) CheckIfCollaboratorByOperationalNeedID(

isCollaborator := false

stmt, err := s.db.PrepareNamed(checkIfCollaboratorByOperationalNeedIDSQL)
stmt, err := s.statements.Get(checkIfCollaboratorByOperationalNeedIDSQL)
if err != nil {
return isCollaborator, err
}
Expand Down
8 changes: 4 additions & 4 deletions pkg/storage/analyzed_auditStore.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ func (s *Store) AnalyzedAuditCreate(logger *zap.Logger, AnalyzedAudit *models.An
if AnalyzedAudit.ID == uuid.Nil {
AnalyzedAudit.ID = uuid.New()
}
stmt, err := s.db.PrepareNamed(analyzedAuditCreate)
stmt, err := s.statements.Get(analyzedAuditCreate)

if err != nil {
logger.Error(
Expand All @@ -57,7 +57,7 @@ func (s *Store) AnalyzedAuditCreate(logger *zap.Logger, AnalyzedAudit *models.An
func (s *Store) AnalyzedAuditGetByModelPlanIDAndDate(logger *zap.Logger, modelPlanID uuid.UUID, date time.Time) (*models.AnalyzedAudit, error) {
analyzedAudit := models.AnalyzedAudit{}

stmt, err := s.db.PrepareNamed(analyzedAuditGetByModelPlanIDAndDate)
stmt, err := s.statements.Get(analyzedAuditGetByModelPlanIDAndDate)
if err != nil {
return nil, err
}
Expand All @@ -78,7 +78,7 @@ func (s *Store) AnalyzedAuditGetByModelPlanIDAndDate(logger *zap.Logger, modelPl
func (s *Store) AnalyzedAuditGetByModelPlanIDsAndDate(logger *zap.Logger, modelPlanIDs []uuid.UUID, date time.Time) ([]*models.AnalyzedAudit, error) {
analyzedAudits := []*models.AnalyzedAudit{}

stmt, err := s.db.PrepareNamed(analyzedAuditGetByModelPlanIDsAndDate)
stmt, err := s.statements.Get(analyzedAuditGetByModelPlanIDsAndDate)
if err != nil {
return nil, err
}
Expand All @@ -99,7 +99,7 @@ func (s *Store) AnalyzedAuditGetByModelPlanIDsAndDate(logger *zap.Logger, modelP
func (s *Store) AnalyzedAuditGetByDate(_ *zap.Logger, date time.Time) ([]*models.AnalyzedAudit, error) {
var analyzedAudits []*models.AnalyzedAudit

stmt, err := s.db.PrepareNamed(analyzedAuditGetByDate)
stmt, err := s.statements.Get(analyzedAuditGetByDate)
if err != nil {
return nil, err
}
Expand Down
6 changes: 3 additions & 3 deletions pkg/storage/audit_changeStore.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ var auditChangeCollectionByPrimaryKeyOrForeignKeyAndDate string
func (s *Store) AuditChangeCollectionByIDAndTable(logger *zap.Logger, tableName string, primaryKey uuid.UUID) ([]*models.AuditChange, error) {
auditChanges := []*models.AuditChange{}

stmt, err := s.db.PrepareNamed(auditChangeCollectionByIDAndTable)
stmt, err := s.statements.Get(auditChangeCollectionByIDAndTable)
if err != nil {
return nil, err

Expand Down Expand Up @@ -54,7 +54,7 @@ func (s *Store) AuditChangeCollectionByIDAndTableAndField(logger *zap.Logger, ta

orderedQuery = orderedQuery + orderClause

stmt, err := s.db.PrepareNamed(orderedQuery)
stmt, err := s.statements.Get(orderedQuery)
if err != nil {
return nil, err

Expand Down Expand Up @@ -86,7 +86,7 @@ func (s *Store) AuditChangeCollectionByPrimaryKeyOrForeignKeyAndDate(logger *zap

orderedQuery = orderedQuery + orderClause

stmt, err := s.db.PrepareNamed(orderedQuery)
stmt, err := s.statements.Get(orderedQuery)
if err != nil {
return nil, err

Expand Down
4 changes: 2 additions & 2 deletions pkg/storage/existing_modelStore.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ var existingModelGetByModelPlanIDLoaderSQL string
func (s *Store) ExistingModelGetByIDLOADER(logger *zap.Logger, paramTableJSON string) ([]*models.ExistingModel, error) {
eMSlice := []*models.ExistingModel{}

stmt, err := s.db.PrepareNamed(existingModelGetByModelPlanIDLoaderSQL)
stmt, err := s.statements.Get(existingModelGetByModelPlanIDLoaderSQL)
if err != nil {
return nil, err
}
Expand All @@ -38,7 +38,7 @@ func (s *Store) ExistingModelGetByIDLOADER(logger *zap.Logger, paramTableJSON st
// ExistingModelCollectionGet returns a list of existing models
func (s *Store) ExistingModelCollectionGet(logger *zap.Logger) ([]*models.ExistingModel, error) {
existingModels := []*models.ExistingModel{}
stmt, err := s.db.PrepareNamed(existingModelCollectionGetSQL)
stmt, err := s.statements.Get(existingModelCollectionGetSQL)
if err != nil {
return nil, err
}
Expand Down
4 changes: 2 additions & 2 deletions pkg/storage/existing_model_linkStore.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ var existingModelLinkGetByModelPlanIDLoaderSQL string
func (s *Store) ExistingModelLinkGetByModelPlanIDLOADER(logger *zap.Logger, paramTableJSON string) ([]*models.ExistingModelLink, error) {
var linkSlice []*models.ExistingModelLink

stmt, err := s.db.PrepareNamed(existingModelLinkGetByModelPlanIDLoaderSQL)
stmt, err := s.statements.Get(existingModelLinkGetByModelPlanIDLoaderSQL)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -84,7 +84,7 @@ func (s *Store) ExistingModelLinksUpdate(logger *zap.Logger, userID uuid.UUID, m
func (s *Store) ExistingModelLinkGetByID(logger *zap.Logger, id uuid.UUID) (*models.ExistingModelLink, error) {
link := models.ExistingModelLink{}

statement, err := s.db.PrepareNamed(existingModelLinkGetByIDSQL)
statement, err := s.statements.Get(existingModelLinkGetByIDSQL)
if err != nil {
return nil, err
}
Expand Down
19 changes: 10 additions & 9 deletions pkg/storage/model_planStore.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ var modelPlanGetByIDLoaderSQL string
func (s *Store) ModelPlanGetByModelPlanIDLOADER(logger *zap.Logger, paramTableJSON string) ([]*models.ModelPlan, error) {
var planSlice []*models.ModelPlan

stmt, err := s.db.PrepareNamed(modelPlanGetByIDLoaderSQL)
stmt, err := s.statements.Get(modelPlanGetByIDLoaderSQL)
if err != nil {
return nil, err
}
Expand All @@ -70,7 +70,7 @@ func (s *Store) ModelPlanCreate(logger *zap.Logger, plan *models.ModelPlan) (*mo
if plan.ID == uuid.Nil {
plan.ID = uuid.New()
}
stmt, err := s.db.PrepareNamed(modelPlanCreateSQL)
stmt, err := s.statements.Get(modelPlanCreateSQL)
if err != nil {
logger.Error(
fmt.Sprintf("Failed to create model plan with error %s", err),
Expand Down Expand Up @@ -99,7 +99,7 @@ func (s *Store) ModelPlanCreate(logger *zap.Logger, plan *models.ModelPlan) (*mo
// ModelPlanUpdate updates a model plan
func (s *Store) ModelPlanUpdate(logger *zap.Logger, plan *models.ModelPlan) (*models.ModelPlan, error) {

stmt, err := s.db.PrepareNamed(modelPlanUpdateSQL)
stmt, err := s.statements.Get(modelPlanUpdateSQL)
if err != nil {
logger.Error(
fmt.Sprintf("Failed to update system intake %s", err),
Expand Down Expand Up @@ -130,7 +130,7 @@ func (s *Store) ModelPlanUpdate(logger *zap.Logger, plan *models.ModelPlan) (*mo
// ModelPlanGetByID returns a model plan for a given ID
func (s *Store) ModelPlanGetByID(logger *zap.Logger, id uuid.UUID) (*models.ModelPlan, error) {
plan := models.ModelPlan{}
stmt, err := s.db.PrepareNamed(modelPlanGetByIDSQL)
stmt, err := s.statements.Get(modelPlanGetByIDSQL)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -158,7 +158,7 @@ func (s *Store) ModelPlanGetByID(logger *zap.Logger, id uuid.UUID) (*models.Mode
// ModelPlanGetByName returns a model plan for a given ID
func (s *Store) ModelPlanGetByName(logger *zap.Logger, modelName string) (*models.ModelPlan, error) {
plan := models.ModelPlan{}
stmt, err := s.db.PrepareNamed(modelPlanGetByNameSQL)
stmt, err := s.statements.Get(modelPlanGetByNameSQL)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -187,7 +187,7 @@ func (s *Store) ModelPlanGetByName(logger *zap.Logger, modelName string) (*model
func (s *Store) ModelPlanCollection(logger *zap.Logger, archived bool) ([]*models.ModelPlan, error) {
var modelPlans []*models.ModelPlan

stmt, err := s.db.PrepareNamed(modelPlanCollectionWhereArchivedSQL)
stmt, err := s.statements.Get(modelPlanCollectionWhereArchivedSQL)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -216,7 +216,7 @@ func (s *Store) ModelPlanCollection(logger *zap.Logger, archived bool) ([]*model
func (s *Store) ModelPlanCollectionCollaboratorOnly(logger *zap.Logger, archived bool, userID uuid.UUID) ([]*models.ModelPlan, error) {
modelPlans := []*models.ModelPlan{}

stmt, err := s.db.PrepareNamed(modelPlanCollectionByCollaboratorSQL)
stmt, err := s.statements.Get(modelPlanCollectionByCollaboratorSQL)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -246,10 +246,11 @@ func (s *Store) ModelPlanCollectionCollaboratorOnly(logger *zap.Logger, archived
func (s *Store) ModelPlanCollectionWithCRTDLS(logger *zap.Logger, archived bool) ([]*models.ModelPlan, error) {
modelPlans := []*models.ModelPlan{}

stmt, err := s.db.PrepareNamed(modelPlanCollectionWithCRTDlSQL)
stmt, err := s.statements.Get(modelPlanCollectionWithCRTDlSQL)
if err != nil {
return nil, err
}

arg := map[string]interface{}{
"archived": archived,
}
Expand All @@ -273,7 +274,7 @@ func (s *Store) ModelPlanCollectionWithCRTDLS(logger *zap.Logger, archived bool)

// ModelPlanDeleteByID deletes a model plan for a given ID
func (s *Store) ModelPlanDeleteByID(logger *zap.Logger, id uuid.UUID) (sql.Result, error) {
statement, err := s.db.PrepareNamed(modelPlanDeleteByID)
statement, err := s.statements.Get(modelPlanDeleteByID)
if err != nil {
return nil, err
}
Expand Down
79 changes: 79 additions & 0 deletions pkg/storage/namedstatements/cache.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package namedstatements

import (
"errors"
"sync"

"github.com/jmoiron/sqlx"
)

// Cache is a cache of prepared statements.
type Cache struct {
db *sqlx.DB
preparedStatements map[string]*sqlx.NamedStmt
lock sync.RWMutex
}

// NewCache initializes a new Cache instance with the provided database.
func NewCache(db *sqlx.DB) *Cache {
return &Cache{
db: db,
preparedStatements: make(map[string]*sqlx.NamedStmt),
}
}

// Get returns a prepared statement for the provided query.
func (n *Cache) Get(query string) (*sqlx.NamedStmt, error) {
ClayBenson94 marked this conversation as resolved.
Show resolved Hide resolved
n.lock.RLock()
storedStatement, foundPreparedStatement := n.preparedStatements[query]
n.lock.RUnlock()

if foundPreparedStatement {
return storedStatement, nil
}

n.lock.Lock()
defer n.lock.Unlock()

// Check again to ensure no other goroutine prepared the statement since our previous check.
// We must assert this as there is a potential for a prepared statement overwrite between the
// first check and the write lock acquisition, however minor the chance.
if storedStatement, foundPreparedStatement = n.preparedStatements[query]; foundPreparedStatement {
return storedStatement, nil
}

preparedStatement, err := n.db.PrepareNamed(query)
if err != nil {
return nil, err
}

n.preparedStatements[query] = preparedStatement
return preparedStatement, nil
}

// Close releases all resources and closes all prepared statements.
func (n *Cache) Close() error {
n.lock.Lock()
defer n.lock.Unlock()

var errs []error

for _, stmt := range n.preparedStatements {
if err := stmt.Close(); err != nil {
errs = append(errs, err)
}
}

// Clear the map after attempting to close all statements
n.preparedStatements = make(map[string]*sqlx.NamedStmt)

if len(errs) > 0 {
msg := "Errors while closing prepared statements: "
for _, err := range errs {
msg += err.Error() + "; "
}
return errors.New(msg)
}

return nil
}
6 changes: 3 additions & 3 deletions pkg/storage/nda_agreementStore.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ var ndaAgreementInsertSQL string
func (s *Store) NDAAgreementGetByUserID(logger *zap.Logger, userID uuid.UUID) (*models.NDAAgreement, error) {
nda := models.NDAAgreement{}

statement, err := s.db.PrepareNamed(ndaAgreementGetByUserIDSQL)
statement, err := s.statements.Get(ndaAgreementGetByUserIDSQL)
if err != nil {
return nil, err
}
Expand All @@ -47,7 +47,7 @@ func (s *Store) NDAAgreementGetByUserID(logger *zap.Logger, userID uuid.UUID) (*
// NDAAgreementUpdate updates an nda agreement based on userID
func (s *Store) NDAAgreementUpdate(logger *zap.Logger, nda *models.NDAAgreement) (*models.NDAAgreement, error) {

statement, err := s.db.PrepareNamed(ndaAgreementUpdateSQL)
statement, err := s.statements.Get(ndaAgreementUpdateSQL)
if err != nil {
return nil, err
}
Expand All @@ -66,7 +66,7 @@ func (s *Store) NDAAgreementCreate(logger *zap.Logger, nda *models.NDAAgreement)

nda.ID = utilityUUID.ValueOrNewUUID(nda.ID)

statement, err := s.db.PrepareNamed(ndaAgreementInsertSQL)
statement, err := s.statements.Get(ndaAgreementInsertSQL)
if err != nil {
return nil, err
}
Expand Down
Loading