| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 } |
| OLD | NEW |