From 57d4790b423fa01dbac2b7ffd53e3d3d34c37c22 Mon Sep 17 00:00:00 2001 From: Jacob Brewer Date: Sat, 18 Jan 2025 13:42:27 +0000 Subject: [PATCH] feat(comments): Updating comments for methods within the library (#89) * Adding comments to methods * removing redunant else for efficency --- joiner.go | 1 + loader.go | 15 +++++++++------ patch.go | 7 +++++++ sql.go | 36 +++++++++++++++++++++++++++++------- 4 files changed, 46 insertions(+), 13 deletions(-) diff --git a/joiner.go b/joiner.go index c4fa5d5..16d8e99 100644 --- a/joiner.go +++ b/joiner.go @@ -1,5 +1,6 @@ package patcher +// Joiner is an interface that can be used to specify the JOIN clause to use when the SQL is being generated. type Joiner interface { Join() (string, []any) } diff --git a/loader.go b/loader.go index 55260c8..3239448 100644 --- a/loader.go +++ b/loader.go @@ -12,19 +12,22 @@ var ( ErrInvalidType = errors.New("invalid type: must pointer to struct") ) -// LoadDiff inserts the fields provided in the new struct pointer into the old struct pointer and injects the new -// values into the old struct +// LoadDiff inserts the fields from the new struct pointer into the old struct pointer, updating the old struct. // -// Note that it only pushes non-zero value updates, meaning you cannot set any field to zero, the empty string, etc. -// This is configurable by setting the includeZeroValues option to true or for nil values by setting includeNilValues. +// Note that it only updates non-zero value fields, meaning you cannot set any field to zero, the empty string, etc. +// This behavior is configurable by setting the includeZeroValues option to true or for nil values by setting includeNilValues. // Please see the LoaderOption's for more configuration options. // -// This can be if you are inserting a patch into an existing object but require a new object to be returned with -// all fields +// This function is useful if you are inserting a patch into an existing object but require a new object to be returned with +// all fields updated. func LoadDiff[T any](old *T, newT *T, opts ...PatchOpt) error { return newPatchDefaults(opts...).loadDiff(old, newT) } +// loadDiff inserts the fields provided in the new struct pointer into the old struct pointer and injects the new +// values into the old struct. It only pushes non-zero value updates, meaning you cannot set any field to zero, +// the empty string, etc. This is configurable by setting the includeZeroValues option to true or for nil values +// by setting includeNilValues. It handles embedded structs and recursively calls loadDiff for nested structs. func (s *SQLPatch) loadDiff(old, newT any) error { if !isPointerToStruct(old) || !isPointerToStruct(newT) { return ErrInvalidType diff --git a/patch.go b/patch.go index 5d6a87a..82a6599 100644 --- a/patch.go +++ b/patch.go @@ -96,6 +96,7 @@ func newPatchDefaults(opts ...PatchOpt) *SQLPatch { return p } +// Fields returns the fields to update in the SQL statement func (s *SQLPatch) Fields() []string { if len(s.fields) == 0 { // Default behaviour is to return nil if there are no fields @@ -104,6 +105,7 @@ func (s *SQLPatch) Fields() []string { return s.fields } +// Args returns the arguments to use in the SQL statement func (s *SQLPatch) Args() []any { if len(s.args) == 0 { // Default behaviour is to return nil if there are no args @@ -112,6 +114,7 @@ func (s *SQLPatch) Args() []any { return s.args } +// validatePerformPatch validates the SQLPatch for the PerformPatch method func (s *SQLPatch) validatePerformPatch() error { if s.db == nil { return ErrNoDatabaseConnection @@ -128,6 +131,7 @@ func (s *SQLPatch) validatePerformPatch() error { return nil } +// validateSQLGen validates the SQLPatch for the SQLGen method func (s *SQLPatch) validateSQLGen() error { if s.table == "" { return ErrNoTable @@ -142,6 +146,7 @@ func (s *SQLPatch) validateSQLGen() error { return nil } +// shouldIncludeNil determines whether the field should be included in the patch func (s *SQLPatch) shouldIncludeNil(tag string) bool { if s.includeNilValues { return true @@ -150,6 +155,7 @@ func (s *SQLPatch) shouldIncludeNil(tag string) bool { return s.shouldOmitEmpty(tag) } +// shouldIncludeZero determines whether zero values should be included in the patch func (s *SQLPatch) shouldIncludeZero(tag string) bool { if s.includeZeroValues { return true @@ -158,6 +164,7 @@ func (s *SQLPatch) shouldIncludeZero(tag string) bool { return s.shouldOmitEmpty(tag) } +// shouldOmitEmpty determines whether the field should be omitted if it is empty func (s *SQLPatch) shouldOmitEmpty(tag string) bool { if tag != "" { tags := strings.Split(tag, TagOptSeparator) diff --git a/sql.go b/sql.go index ca306be..f45299c 100644 --- a/sql.go +++ b/sql.go @@ -19,12 +19,18 @@ var ( ErrNoChanges = errors.New("no changes detected between the old and new objects") ) +// NewSQLPatch creates a new SQLPatch instance with the given resource and options. +// It initializes the SQLPatch with default settings and generates the SQL patch +// for the provided resource by processing its fields and applying the necessary tags and options. func NewSQLPatch(resource any, opts ...PatchOpt) *SQLPatch { sqlPatch := newPatchDefaults(opts...) sqlPatch.patchGen(resource) return sqlPatch } +// patchGen generates the SQL patch for the given resource. +// It processes the fields of the struct, applying the necessary tags and options, +// and prepares the SQL update statement components (fields and arguments). func (s *SQLPatch) patchGen(resource any) { // If the resource is a pointer, we need to dereference it to get the value if reflect.TypeOf(resource).Kind() == reflect.Ptr { @@ -96,11 +102,9 @@ func (s *SQLPatch) patchGen(resource any) { addField() - var val reflect.Value + val := fVal if fVal.Kind() == reflect.Ptr { val = fVal.Elem() - } else { - val = fVal } switch val.Kind() { @@ -123,11 +127,17 @@ func (s *SQLPatch) patchGen(resource any) { } } +// GenerateSQL generates the SQL update statement and its arguments for the given resource. +// It creates a new SQLPatch instance with the provided options, processes the resource's fields, +// and constructs the SQL update statement along with the necessary arguments. func GenerateSQL(resource any, opts ...PatchOpt) (string, []any, error) { - sqlPatch := NewSQLPatch(resource, opts...) - return sqlPatch.GenerateSQL() + return NewSQLPatch(resource, opts...).GenerateSQL() } +// GenerateSQL constructs the SQL update statement and its arguments. +// It validates the SQL generation process, builds the SQL update statement +// with the table name, join clauses, set clauses, and where clauses, +// and returns the final SQL string along with the arguments. func (s *SQLPatch) GenerateSQL() (string, []any, error) { if err := s.validateSQLGen(); err != nil { return "", nil, fmt.Errorf("validate perform patch: %w", err) @@ -166,11 +176,16 @@ func (s *SQLPatch) GenerateSQL() (string, []any, error) { return sqlBuilder.String(), args, nil } +// PerformPatch executes the SQL update statement for the given resource. +// It creates a new SQLPatch instance with the provided options, generates the SQL update statement, +// and executes it using the database connection. func PerformPatch(resource any, opts ...PatchOpt) (sql.Result, error) { - sqlPatch := NewSQLPatch(resource, opts...) - return sqlPatch.PerformPatch() + return NewSQLPatch(resource, opts...).PerformPatch() } +// PerformDiffPatch executes the SQL update statement for the differences between the old and new resources. +// It creates a new SQLPatch instance by comparing the old and new resources, generates the SQL update statement, +// and executes it using the database connection. func PerformDiffPatch[T any](old, newT *T, opts ...PatchOpt) (sql.Result, error) { sqlPatch, err := NewDiffSQLPatch(old, newT, opts...) if err != nil { @@ -180,6 +195,10 @@ func PerformDiffPatch[T any](old, newT *T, opts ...PatchOpt) (sql.Result, error) return sqlPatch.PerformPatch() } +// PerformPatch executes the SQL update statement for the current SQLPatch instance. +// It validates the SQL generation process, constructs the SQL update statement and its arguments, +// and executes the statement using the database connection. +// It returns the result of the SQL execution or an error if the process fails. func (s *SQLPatch) PerformPatch() (sql.Result, error) { if err := s.validatePerformPatch(); err != nil { return nil, fmt.Errorf("validate perform patch: %w", err) @@ -193,6 +212,9 @@ func (s *SQLPatch) PerformPatch() (sql.Result, error) { return s.db.Exec(sqlStr, args...) } +// NewDiffSQLPatch creates a new SQLPatch instance by comparing the old and new resources. +// It initializes the SQLPatch with default settings, loads the differences between the old and new resources, +// and prepares the SQL update statement components (fields and arguments) for the differences. func NewDiffSQLPatch[T any](old, newT *T, opts ...PatchOpt) (*SQLPatch, error) { if !isPointerToStruct(old) || !isPointerToStruct(newT) { return nil, ErrInvalidType