Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: omitempty and omitnil struct tags #309

Merged
merged 6 commits into from
Oct 16, 2023

Conversation

simon-a-j
Copy link
Contributor

@simon-a-j simon-a-j commented Oct 11, 2021

There are a couple of open issues which I think would be most elegantly resolved by the introduction of omitempty and/or omitnil struct tags: #174, #234. This PR introduces both tags.

This provides for much greater flexibility when handling partial inserts or updates. For example, we may handle a partial update as a struct of pointers, where null values are not to be updated.

1. omitnil

type PersonUpdate struct {
	Name    *string `db:"name" goqu:"omitnil"`
	Address *string `db:"address" goqu:"omitnil"`
}
address := "Test"
i := item{Address: &testString, Address2: &emptyString}
insertSQL, args, _ := goqu.Insert("items").Rows(i).ToSQL()
fmt.Println(insertSQL, args)

Output before this PR:

INSERT INTO "items" ("address", "name") VALUES ('Test', NULL) []

Output after this PR:

INSERT INTO "items" ("address") VALUES ('Test') []

2. omitempty

type item struct {
	Name    string `db:"name" goqu:"omitempty"`
	Address string `db:"address" goqu:"omitempty"`
}
i := item{Address: "address"}

insertSQL, args, _ := goqu.Insert("items").Rows(i).ToSQL()
fmt.Println(insertSQL, args)

Output before this PR:

INSERT INTO "items" ("address", "name") VALUES ('address', '') []

Output after this PR:

INSERT INTO "items" ("address") VALUES ('address') []

3. Discussion Items

  1. I have adjusted the implementation of util.IsEmptyValue. Previously it did NOT return true for zero structs. The new implementation uses reflect.IsZero which returns true for zero structs.
    • The reason for this is that it allows omitempty to work with structs that implement the Valuer interface (like NullString) in the way we'd expect - ie. a Valuer without a value should be omitted.
    • It also allows defaultifempty to work similarly with these structs, which will change the behaviour of existing code if anyone annotated Valuer struct fields previously.
    • I can't see a good reason util.IsEmptyValue was previously implemented as it was, but am very open to feedback if I missed something or if the retrospective behaviour change is undesirable.
  2. The *_example_test.go tests are more extensive than the examples included in documentation. I thought this was the cleanest place to put the extra tests.

@simon-a-j
Copy link
Contributor Author

@doug-martin I planned to run CI workflows before marking ready to review, so if you are happy to approve running workflows that would be awesome :)

@codecov
Copy link

codecov bot commented Oct 11, 2021

Codecov Report

Merging #309 (293c6da) into master (a7630f7) will increase coverage by 0.00%.
The diff coverage is 94.73%.

Impacted file tree graph

@@           Coverage Diff           @@
##           master     #309   +/-   ##
=======================================
  Coverage   96.89%   96.90%           
=======================================
  Files          62       62           
  Lines        3477     3485    +8     
=======================================
+ Hits         3369     3377    +8     
  Misses         92       92           
  Partials       16       16           
Flag Coverage Δ
unittests 96.90% <94.73%> (+<0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Impacted Files Coverage Δ
exp/record.go 87.09% <92.30%> (+1.91%) ⬆️
internal/util/column_map.go 100.00% <100.00%> (ø)
internal/util/reflect.go 98.95% <100.00%> (-0.09%) ⬇️
exp/exp.go 71.42% <0.00%> (ø)
insert_dataset.go 100.00% <0.00%> (ø)
exp/insert_clauses.go 100.00% <0.00%> (ø)
sqlgen/insert_sql_generator.go 100.00% <0.00%> (ø)
exp/bool.go 93.33% <0.00%> (+0.11%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update a7630f7...293c6da. Read the comment docs.

@simon-a-j simon-a-j changed the title WIP: omitempty and omitnil struct tags feat: omitempty and omitnil struct tags Oct 12, 2021
@simon-a-j
Copy link
Contributor Author

I feel this is in reasonable shape to review. The coverage is down due to an existing uncovered path which I think should be unreachable. Happy to resolve if preferable, but it means we need to expose that logic outside the package and I’m not sure it’s worthwhile.

@simon-a-j simon-a-j marked this pull request as ready for review October 12, 2021 22:37
docs/inserting.md Outdated Show resolved Hide resolved
@alyhegazy
Copy link

Any updates on this? Would be a useful feature to get this merged.

@pravinchandar
Copy link

Would be keen to know the progress on this?

@dvaldivia
Copy link

This should be taken imo

@funkyshu funkyshu merged commit 34d377d into doug-martin:master Oct 16, 2023
@iredmail
Copy link

Dear @funkyshu

Do you have time to take a look at other PRs? Seems this project doesn't have any other maintainers, and no others have privilege to update repo.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants