Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(6)

Side by Side Diff: service/datastore/properties.go

Issue 1345043005: Fix zero time bug (Closed) Base URL: https://github.com/luci/gae.git@master
Patch Set: Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 package datastore 5 package datastore
6 6
7 import ( 7 import (
8 "encoding/base64" 8 "encoding/base64"
9 "errors" 9 "errors"
10 "fmt" 10 "fmt"
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after
263 err := error(nil) 263 err := error(nil)
264 if checkValid && !x.Valid() { 264 if checkValid && !x.Valid() {
265 err = errors.New("invalid GeoPoint value") 265 err = errors.New("invalid GeoPoint value")
266 } 266 }
267 return PTGeoPoint, err 267 return PTGeoPoint, err
268 default: 268 default:
269 return PTUnknown, fmt.Errorf("gae: Property has bad type %T", v) 269 return PTUnknown, fmt.Errorf("gae: Property has bad type %T", v)
270 } 270 }
271 } 271 }
272 272
273 // timeLocationsEqual tests if two time.Location are equal. 273 // timeLocationIsUTC tests if two time.Location are equal.
274 // 274 //
275 // This is tricky using the standard time API, as time is implicitly normalized 275 // This is tricky using the standard time API, as time is implicitly normalized
276 // to UTC and all equality checks are performed relative to that normalized 276 // to UTC and all equality checks are performed relative to that normalized
277 // time. To compensate, we instantiate two new time.Time using the respective 277 // time. To compensate, we instantiate two new time.Time using the respective
278 // Locations. 278 // Locations.
279 func timeLocationIsUTC(l *time.Location) bool { 279 func timeLocationIsUTC(l *time.Location) bool {
280 return time.Date(1970, 1, 1, 0, 0, 0, 0, l).Equal(utcTestTime) 280 return time.Date(1970, 1, 1, 0, 0, 0, 0, l).Equal(utcTestTime)
281 } 281 }
282 282
283 // UpconvertUnderlyingType takes an object o, and attempts to convert it to 283 // UpconvertUnderlyingType takes an object o, and attempts to convert it to
(...skipping 17 matching lines...) Expand all
301 } 301 }
302 case reflect.Float32, reflect.Float64: 302 case reflect.Float32, reflect.Float64:
303 o = v.Float() 303 o = v.Float()
304 case reflect.Slice: 304 case reflect.Slice:
305 if t.Elem().Kind() == reflect.Uint8 { 305 if t.Elem().Kind() == reflect.Uint8 {
306 o = v.Bytes() 306 o = v.Bytes()
307 } 307 }
308 case reflect.Struct: 308 case reflect.Struct:
309 if t == typeOfTime { 309 if t == typeOfTime {
310 // time in a Property can only hold microseconds 310 // time in a Property can only hold microseconds
311 » » » o = v.Interface().(time.Time).Round(time.Microsecond) 311 » » » tim := v.Interface().(time.Time)
312 » » » if !tim.IsZero() {
313 » » » » o = v.Interface().(time.Time).Round(time.Microse cond)
314 » » » }
312 } 315 }
313 } 316 }
314 return o 317 return o
315 } 318 }
316 319
317 // Value returns the current value held by this property. It's guaranteed to 320 // Value returns the current value held by this property. It's guaranteed to
318 // be a valid value type (i.e. `p.SetValue(p.Value(), true)` will never return 321 // be a valid value type (i.e. `p.SetValue(p.Value(), true)` will never return
319 // an error). 322 // an error).
320 func (p *Property) Value() interface{} { return p.value } 323 func (p *Property) Value() interface{} { return p.value }
321 324
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
402 case to == p.propType: 405 case to == p.propType:
403 return p.value, nil 406 return p.value, nil
404 407
405 case to == PTInt && p.propType == PTTime: 408 case to == PTInt && p.propType == PTTime:
406 t := p.value.(time.Time) 409 t := p.value.(time.Time)
407 v := uint64(t.Unix())*1e6 + uint64(t.Nanosecond()/1e3) 410 v := uint64(t.Unix())*1e6 + uint64(t.Nanosecond()/1e3)
408 return int64(v), nil 411 return int64(v), nil
409 412
410 case to == PTTime && p.propType == PTInt: 413 case to == PTTime && p.propType == PTInt:
411 v := p.value.(int64) 414 v := p.value.(int64)
412 » » return time.Unix(int64(v/1e6), int64((v%1e6)*1e3)).UTC(), nil 415 » » t := time.Unix(int64(v/1e6), int64((v%1e6)*1e3))
416 » » if t.IsZero() {
417 » » » return time.Time{}, nil
418 » » }
419 » » return t.UTC(), nil
413 420
414 case to == PTString && p.propType == PTBytes: 421 case to == PTString && p.propType == PTBytes:
415 return string(p.value.([]byte)), nil 422 return string(p.value.([]byte)), nil
416 423
417 case to == PTString && p.propType == PTBlobKey: 424 case to == PTString && p.propType == PTBlobKey:
418 return string(p.value.(blobstore.Key)), nil 425 return string(p.value.(blobstore.Key)), nil
419 426
420 case to == PTBytes && p.propType == PTString: 427 case to == PTBytes && p.propType == PTString:
421 return []byte(p.value.(string)), nil 428 return []byte(p.value.(string)), nil
422 429
(...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after
781 dflt = UpconvertUnderlyingType(dflt) 788 dflt = UpconvertUnderlyingType(dflt)
782 cur, err := gm(key) 789 cur, err := gm(key)
783 if err != nil { 790 if err != nil {
784 return dflt 791 return dflt
785 } 792 }
786 if dflt != nil && reflect.TypeOf(cur) != reflect.TypeOf(dflt) { 793 if dflt != nil && reflect.TypeOf(cur) != reflect.TypeOf(dflt) {
787 return dflt 794 return dflt
788 } 795 }
789 return cur 796 return cur
790 } 797 }
OLDNEW
« no previous file with comments | « impl/prod/raw_datastore_type_converter_test.go ('k') | service/datastore/serialize/serialize.go » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698