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

datastore: add omitempty support for time.Time - within isEmptyValue() + updated unit tests #131

Merged
merged 6 commits into from Apr 27, 2018

Conversation

trakhimenok
Copy link
Contributor

There are 4 advantages of this change:

  1. Saves datastore space (and cost).
  2. Should slightly decrease write time & write ops (and costs) for entities with empty indexed time properties.
  3. Avoids noise in the datastore viewer in the form of 0001-01-01 00:00:00 timestamps.
  4. Eliminates need to implement PropertyLoadSaver to achieve the same.

This change modifies func isEmptyValue(). This requires additional type assertion but only for time.Time fields with omitempty label. Ideally isEmptyValue() should be removed completely as it is called just in 1 place inside func saveStructProperty() and it can be a bit optimized. But that would be a too big change and pros are not too big so I believe this can/should be done as a separate PR if desired.

Closes #98

Alternative to PR #101 that seems to get abandoned and has no unit tests.

@googlebot
Copy link
Collaborator

Thanks for your pull request. It looks like this may be your first contribution to a Google open source project (if not, look below for help). Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

📝 Please visit https://cla.developers.google.com/ to sign.

Once you've signed (or fixed any issues), please reply here (e.g. I signed it!) and we'll verify it.


What to do if you already signed the CLA

Individual signers
Corporate signers

1 similar comment
@googlebot
Copy link
Collaborator

Thanks for your pull request. It looks like this may be your first contribution to a Google open source project (if not, look below for help). Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

📝 Please visit https://cla.developers.google.com/ to sign.

Once you've signed (or fixed any issues), please reply here (e.g. I signed it!) and we'll verify it.


What to do if you already signed the CLA

Individual signers
Corporate signers

@trakhimenok
Copy link
Contributor Author

I signed it!

@googlebot
Copy link
Collaborator

CLAs look good, thanks!

1 similar comment
@googlebot
Copy link
Collaborator

CLAs look good, thanks!

@trakhimenok
Copy link
Contributor Author

@sbuss can you please take a look to this PR?

For some reasons CI fails but seems the issue is not related to the change. Related tests are passing:

=== RUN   TestRoundTrip
--- PASS: TestRoundTrip (0.58s)
=== RUN   TestSaveStructOmitEmpty
--- PASS: TestSaveStructOmitEmpty (0.00s)

// }{
// NonEmptyValue: 1,
// OmitEmptyWithValue: 2,
// })
Copy link
Contributor

@mtraver mtraver Apr 12, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove this and add a TODO or note in isEmptyValue.

} else {
expected := make([]string, len(expectedPropNames))
copy(expected, expectedPropNames)
PROPS:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be more readable to sort expectedPropNames and props and then compare with a single loop.

sort.Slice(props, func(i, j int) bool {
	return props[i].Name < props[j].Name
})

for i, _ := range props {
	if props[i].Name != expectedPropNames[i] {
		t.Errorf("Unexpected property: %v", props[i].Name)
	}
}

func TestSaveStructOmitEmpty(t *testing.T) {
expectedPropNames := []string{"EmptyValue", "NonEmptyValue", "OmitEmptyWithValue"}

assert := func(src interface{}) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this be more descriptive, e.g. testFieldsOmitted?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And by "this" I mean assert. This snippet shows more lines than I selected.

@trakhimenok
Copy link
Contributor Author

@mtraver, I've addressed your comments, extended tests and fixed build - tests are passing.

Let me know if I should squash commits or you can do it on merging the PR.

for i := range props {
actualPropNames[i] = props[i].Name
}
// and sort actuals for comparing with already sorted expected names
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: // Sort actuals for comparing with already sorted expected names

func isEmptyValue(v reflect.Value) bool {
switch v.Kind() {
case reflect.Array, reflect.Map, reflect.Slice, reflect.String:
// TODO(perfomance): Only relect.String needed, other property types are not supported (copy/paste from json package)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: relect -> reflect

return v.Len() == 0
case reflect.Bool:
return !v.Bool()
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
return v.Int() == 0
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
// TODO(perfomance): Uint* are unsuported property types - should be removed (copy/paste from json package)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: unsuported -> unsupported

@mtraver
Copy link
Contributor

mtraver commented Apr 16, 2018

Just a few nits, but otherwise looks good.

@sbuss, @broady, could one of you review as well?

@mtraver mtraver requested review from sbuss and broady April 16, 2018 20:32
@sbuss
Copy link
Contributor

sbuss commented Apr 17, 2018

@adams-sarah Can you take a look at this, please?

@trakhimenok
Copy link
Contributor Author

@mtraver may be you can send formal review request to @adams-sarah as @sbuss asked her to review?

@mtraver mtraver requested a review from s-mang April 20, 2018 17:24
@mtraver
Copy link
Contributor

mtraver commented Apr 20, 2018

Done

@s-mang s-mang requested review from zombiezen and removed request for s-mang April 25, 2018 02:19
@zombiezen
Copy link
Contributor

@jba, would you mind taking a look? This change probably also needs to be cherry picked into datastore for GoogleCloudPlatform/google-cloud-go.

@jba
Copy link

jba commented Apr 26, 2018

Thanks for the heads-up. Done in https://code-review.googlesource.com/#/c/gocloud/+/26910.

gopherbot pushed a commit to googleapis/google-cloud-go that referenced this pull request Apr 27, 2018
time.Time fields now support the omitempty tag. A zero time.Time will
not be saved.

Mirrors the corresponding change in the AppEngine datastore client, from
golang/appengine#131.

Change-Id: I3ca875ecff865f3b533305091b86bfaec9a135fc
Reviewed-on: https://code-review.googlesource.com/26910
Reviewed-by: kokoro <noreply+kokoro@google.com>
Reviewed-by: Jean de Klerk <deklerk@google.com>
@trakhimenok
Copy link
Contributor Author

The change was merged in https://code-review.googlesource.com/c/gocloud/+/26910

@jba, @zombiezen can we approve/merge here as well?

@mtraver mtraver merged commit 962cbd1 into golang:master Apr 27, 2018
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.

None yet

6 participants