From f212c4eac0a8f04e3c80af64af19b511a811a114 Mon Sep 17 00:00:00 2001 From: Allain Legacy Date: Fri, 6 Dec 2024 11:32:27 -0500 Subject: [PATCH] CNF-15570: Add support for updating only some fields 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 --- internal/service/common/utils/repository.go | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/internal/service/common/utils/repository.go b/internal/service/common/utils/repository.go index 83d45c55..de626388 100644 --- a/internal/service/common/utils/repository.go +++ b/internal/service/common/utils/repository.go @@ -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) @@ -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) @@ -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