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

Unified Diff: service/datastore/serialize/serialize.go

Issue 1550903002: impl/memory: Fix time serialization encoding. (Closed) Base URL: https://github.com/luci/gae@master
Patch Set: Support PTBytes type, found the "ForIndex" method. Created 5 years 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « service/datastore/properties.go ('k') | service/datastore/serialize/serialize_test.go » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: service/datastore/serialize/serialize.go
diff --git a/service/datastore/serialize/serialize.go b/service/datastore/serialize/serialize.go
index 736010820f222499212728ca30154029a905cc4f..fc47a93ccf0206c31dd50200be1e14c7909a2513 100644
--- a/service/datastore/serialize/serialize.go
+++ b/service/datastore/serialize/serialize.go
@@ -189,16 +189,26 @@ func ReadGeoPoint(buf Buffer) (gp ds.GeoPoint, err error) {
return
}
-// WriteTime writes a time.Time in a byte-sortable way.
+// timeToInt converts a time value to a datastore-appropraite integer value.
//
// This method truncates the time to microseconds and drops the timezone,
// because that's the (undocumented) way that the appengine SDK does it.
+func timeToInt(t time.Time) int64 {
+ t = ds.RoundTime(t)
+ return t.Unix()*1e6 + int64(t.Nanosecond()/1e3)
+}
+
+// WriteTime writes a time to the buffer.
+//
+// The supplied time is rounded via datastore.RoundTime and written as a
+// microseconds-since-epoch integer to comform to datastore storage standards.
func WriteTime(buf Buffer, t time.Time) error {
name, off := t.Zone()
if name != "UTC" || off != 0 {
panic(fmt.Errorf("helper: UTC OR DEATH: %s", t))
}
- _, err := cmpbin.WriteInt(buf, t.Unix()*1e6+int64(t.Nanosecond()/1e3))
+
+ _, err := cmpbin.WriteInt(buf, timeToInt(t))
return err
}
@@ -208,6 +218,7 @@ func ReadTime(buf Buffer) (time.Time, error) {
if err != nil {
return time.Time{}, err
}
+
t := time.Unix(v/1e6, (v%1e6)*1e3)
if t.IsZero() {
return time.Time{}, nil
@@ -225,7 +236,14 @@ func WriteProperty(buf Buffer, context KeyContext, p ds.Property) (err error) {
typb |= 0x80
}
panicIf(buf.WriteByte(typb))
- switch p.Type() {
+
+ err = writeRawProperty(buf, context, p)
+ return
+}
+
+func writeRawProperty(buf Buffer, context KeyContext, p ds.Property) (err error) {
+ p = p.ForIndex()
iannucci 2015/12/30 23:12:24 I think this may end up doing unnecessary copies,
+ switch t := p.Type(); t {
case ds.PTNull:
case ds.PTBool:
b := p.Value().(bool)
@@ -240,16 +258,13 @@ func WriteProperty(buf Buffer, context KeyContext, p ds.Property) (err error) {
_, err = cmpbin.WriteFloat64(buf, p.Value().(float64))
case ds.PTString:
_, err = cmpbin.WriteString(buf, p.Value().(string))
- case ds.PTBytes:
- _, err = cmpbin.WriteBytes(buf, p.Value().([]byte))
- case ds.PTTime:
- err = WriteTime(buf, p.Value().(time.Time))
case ds.PTGeoPoint:
err = WriteGeoPoint(buf, p.Value().(ds.GeoPoint))
case ds.PTKey:
err = WriteKey(buf, context, p.Value().(*ds.Key))
- case ds.PTBlobKey:
- _, err = cmpbin.WriteString(buf, string(p.Value().(blobstore.Key)))
+
+ default:
+ err = fmt.Errorf("unsupported type: %v", t)
}
return
}
@@ -504,35 +519,28 @@ func PropertyMapPartially(k *ds.Key, pm ds.PropertyMap) (ret SerializedPmap) {
}
func toBytesErr(i interface{}, ctx KeyContext) (ret []byte, err error) {
- buf := &bytes.Buffer{}
- switch x := i.(type) {
- case ds.GeoPoint:
- err = WriteGeoPoint(buf, x)
+ buf := bytes.Buffer{}
+ switch t := i.(type) {
case ds.IndexColumn:
- err = WriteIndexColumn(buf, x)
+ err = WriteIndexColumn(&buf, t)
case ds.IndexDefinition:
- err = WriteIndexDefinition(buf, x)
-
- case *ds.Key:
- err = WriteKey(buf, ctx, x)
+ err = WriteIndexDefinition(&buf, t)
case ds.KeyTok:
- err = WriteKeyTok(buf, x)
+ err = WriteKeyTok(&buf, t)
case ds.Property:
- err = WriteProperty(buf, ctx, x)
+ err = WriteProperty(&buf, ctx, t)
case ds.PropertyMap:
- err = WritePropertyMap(buf, ctx, x)
-
- case time.Time:
- err = WriteTime(buf, x)
+ err = WritePropertyMap(&buf, ctx, t)
default:
- err = fmt.Errorf("unknown type for ToBytes: %T", i)
+ err = writeRawProperty(&buf, ctx, ds.MkProperty(i))
}
+
if err == nil {
ret = buf.Bytes()
}
« no previous file with comments | « service/datastore/properties.go ('k') | service/datastore/serialize/serialize_test.go » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698