I am trying to use Google Datastore to store data by Go. Since the EndDate
is optional field, and don't want to store zero value in that field. If I make a pointer for time field, Google Datastore will send an error message - datastore: unsupported struct field type: *time.Time
How can I ignore zero value field in struct?
type Event struct {
StartDate time.Time `datastore:"start_date,noindex" json:"startDate"`
EndDate time.Time `datastore:"end_date,noindex" json:"endDate"`
}
The default saving mechanism does not handle optional fields. A field is either saved all the time, or never. There is no such thing as "only save if it's value does not equal to something".
The "optionally saved property" is considered a custom behavior, a custom saving mechanism, and as such, it has to be implemented manually. Go's way to do this is to implement the PropertyLoadSaver
interface on your struct. Here I present 2 different methods to achieve that:
Here is an example how to do it by manually saving the fields (and excluding EndDate
if it is the zero value):
type Event struct {
StartDate time.Time `datastore:"start_date,noindex" json:"startDate"`
EndDate time.Time `datastore:"end_date,noindex" json:"endDate"`
}
func (e *Event) Save(c chan<- datastore.Property) error {
defer close(c)
// Always save StartDate:
c <- datastore.Property{Name:"start_date", Value:e.StartDate, NoIndex: true}
// Only save EndDate if not zero value:
if !e.EndDate.IsZero() {
c <- datastore.Property{Name:"end_date", Value:e.EndDate, NoIndex: true}
}
return nil
}
func (e *Event) Load(c chan<- datastore.Property) error {
// No change required in loading, call default implementation:
return datastore.LoadStruct(e, c)
}
Here's another way using another struct. The Load()
implementation is always the same, only Save()
differs:
func (e *Event) Save(c chan<- datastore.Property) error {
if !e.EndDate.IsZero() {
// If EndDate is not zero, save as usual:
return datastore.SaveStruct(e, c)
}
// Else we need a struct without the EndDate field:
s := struct{ StartDate time.Time `datastore:"start_date,noindex"` }{e.StartDate}
// Which now can be saved using the default saving mechanism:
return datastore.SaveStruct(&s, c)
}