Created
March 21, 2018 05:59
-
-
Save andizzle/d46b5ff8f740072510baf9686ca0bdff to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package cmds | |
import ( | |
"context" | |
"encoding/json" | |
"errors" | |
"fmt" | |
"strings" | |
d "github.com/opensimsim/utilities/database" | |
) | |
type UpdateCertificateRequirementByIDCmd struct { | |
db d.SQLDb | |
id string | |
companyID string | |
name *string | |
mandatory *bool | |
expires *bool | |
groupType *GroupType | |
subscribers *[]ListItem | |
groups *[]ListItem | |
reminders *[]int | |
desiredGroups map[string]ListItem | |
} | |
func (cmd *UpdateCertificateRequirementByIDCmd) CertUpdateValidate() error { | |
//Perform validation | |
if cmd.name != nil { | |
_name := strings.TrimSpace(*cmd.name) | |
if _name == "" { | |
return errors.New("the name must not be empty") | |
} | |
cmd.name = &_name | |
} | |
//Remove duplicates from reminders | |
if cmd.reminders != nil { | |
_reminders := removeDuplicates(*cmd.reminders) | |
if len(_reminders) == 0 { | |
return errors.New("reminders must have at least 1 unique value") | |
} | |
cmd.reminders = &_reminders | |
} | |
// //Remove duplicates from subscribers | |
if cmd.subscribers != nil { | |
if len(*cmd.subscribers) == 0 { | |
return errors.New("subscribers must have at least 1 unique value") | |
} | |
} | |
if cmd.groups != nil { | |
if len(*cmd.groups) == 0 { | |
return errors.New("groups must have at least 1 unique value") | |
} | |
for _, g := range *cmd.groups { | |
cmd.desiredGroups[g.ID] = g | |
} | |
} | |
return nil | |
} | |
// NewUpdateCertificateRequirementCmd - Create a UpdateCertificateRequirementCmd Command | |
func NewUpdateCertificateRequirementByIDCmd(db d.SQLDb, id, companyID string, name *string, mandatory, expires *bool, groupType *GroupType, groups *[]ListItem, subscribers *[]ListItem, reminders *[]int) (*UpdateCertificateRequirementByIDCmd, error) { | |
cmd := &UpdateCertificateRequirementByIDCmd{ | |
db: db, | |
id: id, | |
companyID: companyID, | |
name: name, | |
mandatory: mandatory, | |
expires: expires, | |
groupType: groupType, | |
reminders: reminders, | |
groups: groups, | |
subscribers: subscribers, | |
} | |
if err := cmd.CertUpdateValidate(); err != nil { | |
return nil, err | |
} | |
return cmd, nil | |
} | |
func (cmd *UpdateCertificateRequirementByIDCmd) syncReqGroup(ctx context.Context, tx d.SQLTx) error { | |
//Determine which items to delete | |
deleteIDs := []interface{}{} | |
stmt2 := ` | |
SELECT id, | |
perspective_id, | |
perspective_type | |
FROM cert_req_group | |
WHERE cert_req_id = ? | |
` | |
currentGroups, err := fetchCurrentGroups(ctx, tx, stmt2, cmd.id) | |
if err != nil { | |
return err | |
} | |
for id, group := range currentGroups { | |
if _, ok := cmd.desiredGroups[id]; !ok { | |
// add to delete id list | |
deleteIDs = append(deleteIDs, group.PK) | |
} else { | |
delete(cmd.desiredGroups, id) | |
} | |
} | |
if len(deleteIDs) > 0 { | |
err = batchDelete(ctx, tx, "cert_req_group", "id",&[]string{"cert_req_id"}[0], &cmd.id, deleteIDs...) | |
} | |
if len(cmd.desiredGroups) > 0 { | |
} | |
return nil | |
} | |
//stmt must include the the entire where statement without placeholders | |
func fetchCurrentGroups(ctx context.Context, tx d.SQLCommon, stmt string, params ...interface{}) (map[string]listItemPK, error) { | |
rows, err := tx.QueryContext(ctx, stmt, params...) | |
if err != nil { | |
return nil, err | |
} | |
defer rows.Close() | |
currentGroups := map[string]listItemPK{} | |
for rows.Next() { | |
var g listItemPK | |
if err := rows.Scan(&g.PK, &g.ID, &g.Type); err != nil { | |
return nil, err | |
} | |
currentGroups[g.ID] = g | |
} | |
if err := rows.Err(); err != nil { | |
return nil, err | |
} | |
return currentGroups, nil | |
} | |
// Handle - is the command handler for UpdateCertificateRequirementCmd | |
func (cmd *UpdateCertificateRequirementByIDCmd) Handle(ctx context.Context) error { | |
tx, err := cmd.db.BeginTx(ctx, nil) | |
if err != nil { | |
return nil | |
} | |
err = cmd.UpdateCert(ctx, tx) | |
//Update Groups | |
if cmd.groups != nil { | |
stmt2 := ` | |
SELECT id, | |
perspective_id, | |
perspective_type | |
FROM cert_req_group | |
WHERE cert_req_id = ? | |
` | |
currentGroups, err := fetchCurrentItems(ctx, tx, stmt2, cmd.id) | |
if err != nil { | |
tx.Rollback() | |
return err | |
} | |
desiredGroups := *cmd.groups | |
//Determine which items to delete | |
deleteIDs := []interface{}{} | |
// If an item is in current, but not in desired, then delete using PK | |
OUTER1: | |
for _, v := range currentGroups { | |
currentID := v.ID | |
//Search for currentID in desiredGroups | |
for _, j := range desiredGroups { | |
if j.ID == currentID { | |
continue OUTER1 | |
} | |
} | |
deleteIDs = append(deleteIDs, v.PK) | |
} | |
//Perform batch delete | |
ownerFieldName := "cert_req_id" | |
err = batchDelete(ctx, tx, "cert_req_group", "id", &ownerFieldName, &cmd.id, deleteIDs...) | |
if err != nil { | |
tx.Rollback() | |
return err | |
} | |
//Determine which items to add | |
insertIDs := []ListItem{} | |
OUTER2: | |
for _, v := range desiredGroups { | |
desiredID := v.ID | |
//Search for desiredID in currentGroups | |
for _, j := range currentGroups { | |
if j.ID == desiredID { | |
continue OUTER2 | |
} | |
} | |
insertIDs = append(insertIDs, ListItem{ | |
ID: desiredID, | |
Type: v.Type, | |
}) | |
} | |
//Perform batch insert | |
if len(insertIDs) != 0 { | |
stmt := d.BulkInsert("cert_req_group", []string{"cert_req_id", "perspective_id", "perspective_type"}, len(insertIDs)) | |
insertData := []interface{}{} | |
for _, v := range insertIDs { | |
insertData = append(insertData, cmd.id, v.ID, v.Type) | |
} | |
_, err := tx.ExecContext(ctx, stmt, insertData...) | |
if err != nil { | |
tx.Rollback() | |
return err | |
} | |
} | |
} | |
//Update Reminders | |
if cmd.reminders != nil { | |
currentReminderDays, err := fetchCurrentReminderDays(ctx, tx, cmd.id) | |
if err != nil { | |
tx.Rollback() | |
return err | |
} | |
desiredReminderDays := *cmd.reminders | |
//Determine which items to delete | |
deleteIDs := []interface{}{} | |
// If an item is in current, but not in desired, then delete using PK | |
OUTER3: | |
for _, v := range currentReminderDays { | |
currentDay := v.OffsetDay | |
//Search for currentDay in desiredReminderDays | |
for _, j := range desiredReminderDays { | |
if j == currentDay { | |
continue OUTER3 | |
} | |
} | |
deleteIDs = append(deleteIDs, v.PK) | |
} | |
//Perform batch delete | |
ownerFieldName := "cert_req_id" | |
err = batchDelete(ctx, tx, "cert_req_reminders", "id", &ownerFieldName, &cmd.id, deleteIDs...) | |
if err != nil { | |
tx.Rollback() | |
return err | |
} | |
//Determine which items to add | |
insertDays := []int{} | |
OUTER4: | |
for _, desiredDay := range desiredReminderDays { | |
//Search for desiredDay in currentReminderDays | |
for _, j := range currentReminderDays { | |
if j.OffsetDay == desiredDay { | |
continue OUTER4 | |
} | |
} | |
insertDays = append(insertDays, desiredDay) | |
} | |
//Perform batch insert | |
if len(insertDays) != 0 { | |
stmt := d.BulkInsert("cert_req_reminders", []string{"cert_req_id", "offset_day"}, len(insertDays)) | |
insertData := []interface{}{} | |
for _, day := range insertDays { | |
insertData = append(insertData, cmd.id, day) | |
} | |
_, err := tx.ExecContext(ctx, stmt, insertData...) | |
if err != nil { | |
tx.Rollback() | |
return err | |
} | |
} | |
} | |
return tx.Commit() | |
} | |
// UpdateCert update the cert itself | |
func (cmd *UpdateCertificateRequirementByIDCmd) UpdateCert(ctx context.Context, tx d.SQLTx) error { | |
//Update fields in the `cert_reqs` table | |
fields := map[string]interface{}{} | |
if cmd.name != nil { | |
fields["name"] = *cmd.name | |
} | |
if cmd.mandatory != nil { | |
var val int | |
if *cmd.mandatory { | |
val = 1 | |
} else { | |
val = 0 | |
} | |
fields["mandatory"] = val | |
} | |
if cmd.expires != nil { | |
var val int | |
if *cmd.expires { | |
val = 1 | |
} else { | |
val = 0 | |
} | |
fields["expires"] = val | |
} | |
if cmd.groupType != nil { | |
fields["group_type"] = *cmd.groupType | |
} | |
if cmd.subscribers != nil { | |
_nl, err := json.Marshal(*cmd.subscribers) | |
if err != nil { | |
return err | |
} | |
nl := string(_nl) | |
fields["sdata"] = nl | |
} | |
if len(fields) > 0 { | |
var updateFields string | |
vals := []interface{}{} | |
for col, val := range fields { | |
updateFields += fmt.Sprintf("%s = ?,", col) | |
vals = append(vals, val) | |
} | |
updateFields = strings.TrimRight(updateFields, ",") | |
vals = append(vals, cmd.id) | |
stmt := fmt.Sprintf("UPDATE cert_reqs SET %s WHERE id = ?;", updateFields) | |
_, err := tx.ExecContext(ctx, stmt, vals...) | |
if err != nil { | |
return err | |
} | |
} | |
return nil | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment