-
Notifications
You must be signed in to change notification settings - Fork 11
/
trb_admin_note_trb_request_document_link.go
140 lines (121 loc) · 4.67 KB
/
trb_admin_note_trb_request_document_link.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
package storage
import (
"context"
"fmt"
"github.com/google/uuid"
"go.uber.org/zap"
"github.com/cmsgov/easi-app/pkg/appcontext"
"github.com/cmsgov/easi-app/pkg/apperrors"
"github.com/cmsgov/easi-app/pkg/models"
)
// Creates multiple link records relating a single TRB admin note to all TRB documents it references
func (s *Store) CreateTRBAdminNoteTRBDocumentLinks(
ctx context.Context,
trbRequestID uuid.UUID,
trbAdminNoteID uuid.UUID,
trbRequestDocumentIDs []uuid.UUID,
) ([]*models.TRBAdminNoteTRBRequestDocumentLink, error) {
creatingUserEUAID := appcontext.Principal(ctx).ID()
links := []*models.TRBAdminNoteTRBRequestDocumentLink{}
for _, documentID := range trbRequestDocumentIDs {
link := models.TRBAdminNoteTRBRequestDocumentLink{
TRBRequestID: trbRequestID,
TRBAdminNoteID: trbAdminNoteID,
TRBRequestDocumentID: documentID,
}
link.ID = uuid.New()
link.CreatedBy = creatingUserEUAID
links = append(links, &link)
}
const trbAdminNoteTRBDocumentLinkCreateSQL = `
INSERT INTO trb_admin_notes_trb_request_documents_links (
id,
trb_request_id,
trb_admin_note_id,
trb_request_document_id,
created_by
) VALUES (
:id,
:trb_request_id,
:trb_admin_note_id,
:trb_request_document_id,
:created_by
) RETURNING *;
`
// insert all links and return the created rows immediately
// see Note [Use NamedQuery to insert multiple records]
createdLinkRows, err := s.db.NamedQuery(trbAdminNoteTRBDocumentLinkCreateSQL, links)
if err != nil {
appcontext.ZLogger(ctx).Error(
fmt.Sprintf("Failed to create links between TRB admin note and TRB documents with error %s", err),
zap.Error(err),
zap.String("user", creatingUserEUAID),
zap.String("trbAdminNoteID", trbAdminNoteID.String()),
)
return nil, err
}
defer createdLinkRows.Close()
// loop through the sqlx.Rows value returned from NamedQuery(), scan the results back into structs
createdLinks := []*models.TRBAdminNoteTRBRequestDocumentLink{}
for createdLinkRows.Next() {
var createdLink models.TRBAdminNoteTRBRequestDocumentLink
err = createdLinkRows.StructScan(&createdLink)
if err != nil {
appcontext.ZLogger(ctx).Error(
fmt.Sprintf("Failed to read results from creating links between TRB admin note and TRB documents with error %s", err),
zap.Error(err),
zap.String("user", creatingUserEUAID),
zap.String("trbAdminNoteID", trbAdminNoteID.String()),
)
return nil, err
}
createdLinks = append(createdLinks, &createdLink)
}
return createdLinks, nil
}
// GetTRBRequestDocumentsByAdminNoteID fetches all TRB request documents linked to a TRB admin note
// This function specifically fetches all documents (even deleted ones), as this function is called by the resolver for TRB Admin Notes,
// which need to display previously deleted document names
func (s *Store) GetTRBRequestDocumentsByAdminNoteID(ctx context.Context, adminNoteID uuid.UUID) ([]*models.TRBRequestDocument, error) {
const trbRequestDocumentsGetByAdminNoteIDSQL = `
SELECT trb_request_documents.*
FROM trb_request_documents
INNER JOIN trb_admin_notes_trb_request_documents_links
ON trb_request_documents.id = trb_admin_notes_trb_request_documents_links.trb_request_document_id
WHERE trb_admin_notes_trb_request_documents_links.trb_admin_note_id = :admin_note_id
`
stmt, err := s.db.PrepareNamed(trbRequestDocumentsGetByAdminNoteIDSQL)
if err != nil {
appcontext.ZLogger(ctx).Error(
fmt.Sprintf("Failed to prepare SQL statement for fetching TRB request documents by admin note ID with error %s", err),
zap.Error(err),
zap.String("adminNoteID", adminNoteID.String()),
)
return nil, err
}
defer stmt.Close()
arg := map[string]interface{}{
"admin_note_id": adminNoteID,
}
documents := []*models.TRBRequestDocument{}
err = stmt.Select(&documents, arg)
if err != nil {
appcontext.ZLogger(ctx).Error(
fmt.Sprintf("Failed to fetch TRB request documents by admin note ID with error %s", err),
zap.Error(err),
zap.String("adminNoteID", adminNoteID.String()),
)
return nil, &apperrors.QueryError{
Err: err,
Model: models.TRBRequestDocument{},
Operation: apperrors.QueryFetch,
}
}
return documents, nil
}
// Note [Use NamedQuery to insert multiple records]
// There are several potential options for inserting multiple records at once;
// Using NamedQuery() allows inserting multiple rows and getting the created rows in a single query, though we have to scan the results back into structs
// We could use NamedExec() to insert multiple rows, but we'd have to do a separate SELECT query to get the results
// Select() doesn't work with inserting multiple values with named arguments
// PrepareNamed() doesn't work when inserting multiple values