Skip to content

Commit

Permalink
CNF-15570: Add support for updating only some fields
Browse files Browse the repository at this point in the history
This makes changes to the Update utility so that it is possible to
request that only some fields be set in the update operation.  This is
to facilitate changes required by the upcoming resource data collector
functionality that will be synchronizing data between ACM and our
persistent storage.

Signed-off-by: Allain Legacy <[email protected]>
  • Loading branch information
alegacy committed Dec 6, 2024
1 parent cf576b1 commit 873408c
Showing 1 changed file with 9 additions and 6 deletions.
15 changes: 9 additions & 6 deletions internal/service/common/utils/repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -150,9 +150,10 @@ func Exists[T db.Model](ctx context.Context, db *pgxpool.Pool, uuid uuid.UUID) (
// is returned.
func Create[T db.Model](ctx context.Context, db *pgxpool.Pool, record T) (*T, error) {
nonNilTags := GetNonNilDBTagsFromStruct(record)
tags := GetAllDBTagsFromStruct(record)

// Return all columns to get any defaulted values that the DB may set
query := psql.Insert(im.Into(record.TableName()), im.Returning("*"))
query := psql.Insert(im.Into(record.TableName()), im.Returning(tags.Columns()...))

// Add columns to the expression. Maintain the order here so that it coincides with the order of the values
columns, values := GetColumnsAndValues(record, nonNilTags)
Expand Down Expand Up @@ -181,16 +182,18 @@ func Create[T db.Model](ctx context.Context, db *pgxpool.Pool, record T) (*T, er
}

// Update attempts to update a record with a matching primary key. The stored record is returned on success; otherwise
// an error is returned.
func Update[T db.Model](ctx context.Context, db *pgxpool.Pool, record T, uuid uuid.UUID) (*T, error) {
tags := GetAllDBTagsFromStruct(record)
// an error is returned. If the `fields` argument is set then only those columns are updated but the returned object
// will contain all columns.
func Update[T db.Model](ctx context.Context, db *pgxpool.Pool, record T, uuid uuid.UUID, fields ...string) (*T, error) {
all := GetAllDBTagsFromStruct(record)
tags := GetDBTagsFromStructFields(record, fields...)

// Set up the arguments to the call to psql.Update(...) by using an array because there's no obvious way to add
// multiple Set(..) operation without having to add them one at a time separately.
mods := []bob.Mod[*dialect.UpdateQuery]{
um.Table(record.TableName()),
um.Where(psql.Quote(record.PrimaryKey()).EQ(psql.Arg(uuid))),
um.Returning(tags.Columns()...)}
um.Returning(all.Columns()...)}

// Add the individual column sets
columns, values := GetColumnsAndValues(record, tags)
Expand All @@ -215,7 +218,7 @@ func Update[T db.Model](ctx context.Context, db *pgxpool.Pool, record T, uuid uu

record, err = pgx.CollectExactlyOneRow(result, pgx.RowToStructByName[T])
if err != nil {
return nil, fmt.Errorf("failed to extract inserted record: %w", err)
return nil, fmt.Errorf("failed to extract updated record: %w", err)
}

return &record, nil
Expand Down

0 comments on commit 873408c

Please sign in to comment.