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

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

Issue 2302743002: Interface update, per-method Contexts. (Closed)
Patch Set: WithoutTransaction, comments, fixes, cleanup. Created 4 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 LUCI Authors. All rights reserved. 1 // Copyright 2015 The LUCI Authors. All rights reserved.
2 // Use of this source code is governed under the Apache License, Version 2.0 2 // Use of this source code is governed under the Apache License, Version 2.0
3 // that can be found in the LICENSE file. 3 // that can be found in the LICENSE file.
4 4
5 package serialize 5 package serialize
6 6
7 import ( 7 import (
8 "bytes" 8 "bytes"
9 "errors" 9 "errors"
10 "fmt" 10 "fmt"
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
68 panicIf(buf.WriteByte(1)) 68 panicIf(buf.WriteByte(1))
69 panicIf(WriteKeyTok(buf, tok)) 69 panicIf(WriteKeyTok(buf, tok))
70 } 70 }
71 return buf.WriteByte(0) 71 return buf.WriteByte(0)
72 } 72 }
73 73
74 // ReadKey deserializes a key from the buffer. The value of context must match 74 // ReadKey deserializes a key from the buffer. The value of context must match
75 // the value of context that was passed to WriteKey when the key was encoded. 75 // the value of context that was passed to WriteKey when the key was encoded.
76 // If context == WithoutContext, then the appid and namespace parameters are 76 // If context == WithoutContext, then the appid and namespace parameters are
77 // used in the decoded Key. Otherwise they're ignored. 77 // used in the decoded Key. Otherwise they're ignored.
78 func ReadKey(buf Buffer, context KeyContext, appid, namespace string) (ret *ds.K ey, err error) { 78 func ReadKey(buf Buffer, context KeyContext, inKC ds.KeyContext) (ret *ds.Key, e rr error) {
79 defer recoverTo(&err) 79 defer recoverTo(&err)
80 actualCtx, e := buf.ReadByte() 80 actualCtx, e := buf.ReadByte()
81 panicIf(e) 81 panicIf(e)
82 82
83 » actualAid, actualNS := "", "" 83 » var kc ds.KeyContext
84 if actualCtx == 1 { 84 if actualCtx == 1 {
85 » » actualAid, _, e = cmpbin.ReadString(buf) 85 » » kc.AppID, _, e = cmpbin.ReadString(buf)
86 panicIf(e) 86 panicIf(e)
87 » » actualNS, _, e = cmpbin.ReadString(buf) 87 » » kc.Namespace, _, e = cmpbin.ReadString(buf)
88 panicIf(e) 88 panicIf(e)
89 } else if actualCtx != 0 { 89 } else if actualCtx != 0 {
90 err = fmt.Errorf("helper: expected actualCtx to be 0 or 1, got % d", actualCtx) 90 err = fmt.Errorf("helper: expected actualCtx to be 0 or 1, got % d", actualCtx)
91 return 91 return
92 } 92 }
93 93
94 if context == WithoutContext { 94 if context == WithoutContext {
95 // overrwrite with the supplied ones 95 // overrwrite with the supplied ones
96 » » actualAid = appid 96 » » kc = inKC
97 » » actualNS = namespace
98 } 97 }
99 98
100 toks := []ds.KeyTok{} 99 toks := []ds.KeyTok{}
101 for { 100 for {
102 ctrlByte, e := buf.ReadByte() 101 ctrlByte, e := buf.ReadByte()
103 panicIf(e) 102 panicIf(e)
104 if ctrlByte == 0 { 103 if ctrlByte == 0 {
105 break 104 break
106 } 105 }
107 if len(toks)+1 > ReadKeyNumToksReasonableLimit { 106 if len(toks)+1 > ReadKeyNumToksReasonableLimit {
108 err = fmt.Errorf( 107 err = fmt.Errorf(
109 "helper: tried to decode huge key with > %d toke ns", 108 "helper: tried to decode huge key with > %d toke ns",
110 ReadKeyNumToksReasonableLimit) 109 ReadKeyNumToksReasonableLimit)
111 return 110 return
112 } 111 }
113 112
114 tok, e := ReadKeyTok(buf) 113 tok, e := ReadKeyTok(buf)
115 panicIf(e) 114 panicIf(e)
116 115
117 toks = append(toks, tok) 116 toks = append(toks, tok)
118 } 117 }
119 118
120 » return ds.NewKeyToks(actualAid, actualNS, toks), nil 119 » return kc.NewKeyToks(toks), nil
121 } 120 }
122 121
123 // WriteKeyTok writes a KeyTok to the buffer. You usually want WriteKey 122 // WriteKeyTok writes a KeyTok to the buffer. You usually want WriteKey
124 // instead of this. 123 // instead of this.
125 func WriteKeyTok(buf Buffer, tok ds.KeyTok) (err error) { 124 func WriteKeyTok(buf Buffer, tok ds.KeyTok) (err error) {
126 // tok.kind ++ typ ++ [tok.stringID || tok.intID] 125 // tok.kind ++ typ ++ [tok.stringID || tok.intID]
127 defer recoverTo(&err) 126 defer recoverTo(&err)
128 _, e := cmpbin.WriteString(buf, tok.Kind) 127 _, e := cmpbin.WriteString(buf, tok.Kind)
129 panicIf(e) 128 panicIf(e)
130 if tok.StringID != "" { 129 if tok.StringID != "" {
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
270 err = WriteGeoPoint(buf, t) 269 err = WriteGeoPoint(buf, t)
271 case *ds.Key: 270 case *ds.Key:
272 err = WriteKey(buf, context, t) 271 err = WriteKey(buf, context, t)
273 272
274 default: 273 default:
275 err = fmt.Errorf("unsupported type: %T", t) 274 err = fmt.Errorf("unsupported type: %T", t)
276 } 275 }
277 return 276 return
278 } 277 }
279 278
280 // ReadProperty reads a Property from the buffer. `context`, `appid`, and 279 // ReadProperty reads a Property from the buffer. `context` and `kc` behave the
281 // `namespace` behave the same way they do for ReadKey, but only have an 280 // same way they do for ReadKey, but only have an effect if the decoded property
282 // effect if the decoded property has a Key value. 281 // has a Key value.
283 func ReadProperty(buf Buffer, context KeyContext, appid, namespace string) (p ds .Property, err error) { 282 func ReadProperty(buf Buffer, context KeyContext, kc ds.KeyContext) (p ds.Proper ty, err error) {
284 val := interface{}(nil) 283 val := interface{}(nil)
285 b, err := buf.ReadByte() 284 b, err := buf.ReadByte()
286 if err != nil { 285 if err != nil {
287 return 286 return
288 } 287 }
289 is := ds.ShouldIndex 288 is := ds.ShouldIndex
290 if (b & 0x80) == 0 { 289 if (b & 0x80) == 0 {
291 is = ds.NoIndex 290 is = ds.NoIndex
292 } 291 }
293 switch ds.PropertyType(b & 0x7f) { 292 switch ds.PropertyType(b & 0x7f) {
294 case ds.PTNull: 293 case ds.PTNull:
295 case ds.PTBool: 294 case ds.PTBool:
296 b, err = buf.ReadByte() 295 b, err = buf.ReadByte()
297 val = (b != 0) 296 val = (b != 0)
298 case ds.PTInt: 297 case ds.PTInt:
299 val, _, err = cmpbin.ReadInt(buf) 298 val, _, err = cmpbin.ReadInt(buf)
300 case ds.PTFloat: 299 case ds.PTFloat:
301 val, _, err = cmpbin.ReadFloat64(buf) 300 val, _, err = cmpbin.ReadFloat64(buf)
302 case ds.PTString: 301 case ds.PTString:
303 val, _, err = cmpbin.ReadString(buf) 302 val, _, err = cmpbin.ReadString(buf)
304 case ds.PTBytes: 303 case ds.PTBytes:
305 val, _, err = cmpbin.ReadBytes(buf) 304 val, _, err = cmpbin.ReadBytes(buf)
306 case ds.PTTime: 305 case ds.PTTime:
307 val, err = ReadTime(buf) 306 val, err = ReadTime(buf)
308 case ds.PTGeoPoint: 307 case ds.PTGeoPoint:
309 val, err = ReadGeoPoint(buf) 308 val, err = ReadGeoPoint(buf)
310 case ds.PTKey: 309 case ds.PTKey:
311 » » val, err = ReadKey(buf, context, appid, namespace) 310 » » val, err = ReadKey(buf, context, kc)
312 case ds.PTBlobKey: 311 case ds.PTBlobKey:
313 s := "" 312 s := ""
314 if s, _, err = cmpbin.ReadString(buf); err != nil { 313 if s, _, err = cmpbin.ReadString(buf); err != nil {
315 break 314 break
316 } 315 }
317 val = blobstore.Key(s) 316 val = blobstore.Key(s)
318 default: 317 default:
319 err = fmt.Errorf("read: unknown type! %v", b) 318 err = fmt.Errorf("read: unknown type! %v", b)
320 } 319 }
321 if err == nil { 320 if err == nil {
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
357 panicIf(e) 356 panicIf(e)
358 for _, r := range rows { 357 for _, r := range rows {
359 _, e := buf.WriteString(r) 358 _, e := buf.WriteString(r)
360 panicIf(e) 359 panicIf(e)
361 } 360 }
362 return 361 return
363 } 362 }
364 363
365 // ReadPropertyMap reads a PropertyMap from the buffer. `context` and 364 // ReadPropertyMap reads a PropertyMap from the buffer. `context` and
366 // friends behave the same way that they do for ReadKey. 365 // friends behave the same way that they do for ReadKey.
367 func ReadPropertyMap(buf Buffer, context KeyContext, appid, namespace string) (p m ds.PropertyMap, err error) { 366 func ReadPropertyMap(buf Buffer, context KeyContext, kc ds.KeyContext) (pm ds.Pr opertyMap, err error) {
368 defer recoverTo(&err) 367 defer recoverTo(&err)
369 368
370 numRows := uint64(0) 369 numRows := uint64(0)
371 numRows, _, e := cmpbin.ReadUint(buf) 370 numRows, _, e := cmpbin.ReadUint(buf)
372 panicIf(e) 371 panicIf(e)
373 if numRows > ReadPropertyMapReasonableLimit { 372 if numRows > ReadPropertyMapReasonableLimit {
374 err = fmt.Errorf("helper: tried to decode map with huge number o f rows %d", numRows) 373 err = fmt.Errorf("helper: tried to decode map with huge number o f rows %d", numRows)
375 return 374 return
376 } 375 }
377 376
378 pm = make(ds.PropertyMap, numRows) 377 pm = make(ds.PropertyMap, numRows)
379 378
380 name, prop := "", ds.Property{} 379 name, prop := "", ds.Property{}
381 for i := uint64(0); i < numRows; i++ { 380 for i := uint64(0); i < numRows; i++ {
382 name, _, e = cmpbin.ReadString(buf) 381 name, _, e = cmpbin.ReadString(buf)
383 panicIf(e) 382 panicIf(e)
384 383
385 numProps, _, e := cmpbin.ReadUint(buf) 384 numProps, _, e := cmpbin.ReadUint(buf)
386 panicIf(e) 385 panicIf(e)
387 if numProps > ReadPropertyMapReasonableLimit { 386 if numProps > ReadPropertyMapReasonableLimit {
388 err = fmt.Errorf("helper: tried to decode map with huge number of properties %d", numProps) 387 err = fmt.Errorf("helper: tried to decode map with huge number of properties %d", numProps)
389 return 388 return
390 } 389 }
391 props := make([]ds.Property, 0, numProps) 390 props := make([]ds.Property, 0, numProps)
392 for j := uint64(0); j < numProps; j++ { 391 for j := uint64(0); j < numProps; j++ {
393 » » » prop, err = ReadProperty(buf, context, appid, namespace) 392 » » » prop, err = ReadProperty(buf, context, kc)
394 panicIf(err) 393 panicIf(err)
395 props = append(props, prop) 394 props = append(props, prop)
396 } 395 }
397 pm[name] = props 396 pm[name] = props
398 } 397 }
399 return 398 return
400 } 399 }
401 400
402 // WriteIndexColumn writes an IndexColumn to the buffer. 401 // WriteIndexColumn writes an IndexColumn to the buffer.
403 func WriteIndexColumn(buf Buffer, c ds.IndexColumn) (err error) { 402 func WriteIndexColumn(buf Buffer, c ds.IndexColumn) (err error) {
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after
612 } 611 }
613 } 612 }
614 613
615 func recoverTo(err *error) { 614 func recoverTo(err *error) {
616 if r := recover(); r != nil { 615 if r := recover(); r != nil {
617 if rerr := r.(parseError); rerr != nil { 616 if rerr := r.(parseError); rerr != nil {
618 *err = error(rerr) 617 *err = error(rerr)
619 } 618 }
620 } 619 }
621 } 620 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698