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 "errors" | 8 "errors" |
9 "fmt" | 9 "fmt" |
10 "math" | 10 "math" |
(...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
307 } | 307 } |
308 p.propType = pt | 308 p.propType = pt |
309 p.value = value | 309 p.value = value |
310 p.indexSetting = is | 310 p.indexSetting = is |
311 if t == typeOfByteSlice { | 311 if t == typeOfByteSlice { |
312 p.indexSetting = NoIndex | 312 p.indexSetting = NoIndex |
313 } | 313 } |
314 return | 314 return |
315 } | 315 } |
316 | 316 |
317 // PropertyLoadSaver may be implemented by a user type, and Interface will | 317 // MetaGetter is a subinterface of PropertyLoadSaver, but is also used to |
318 // use this interface to serialize the type instead of trying to automatically | 318 // abstract the meta argument for RawInterface.GetMulti. |
319 // create a serialization codec for it with helper.GetPLS. | 319 type MetaGetter interface { |
320 type PropertyLoadSaver interface { | |
321 » // Load takes the values from the given map and attempts to save them in
to | |
322 » // the underlying object (usually a struct or a PropertyMap). If a fatal | |
323 » // error occurs, it's returned via error. If non-fatal conversion errors | |
324 » // occur, error will be a MultiError containing one or more ErrFieldMism
atch | |
325 » // objects. | |
326 » Load(PropertyMap) error | |
327 | |
328 » // Save returns the current property as a PropertyMap. if withMeta is tr
ue, | |
329 » // then the PropertyMap contains all the metadata (e.g. '$meta' fields) | |
330 » // which was held by this PropertyLoadSaver. | |
331 » Save(withMeta bool) (PropertyMap, error) | |
332 | |
333 // GetMeta will get information about the field which has the struct tag
in | 320 // GetMeta will get information about the field which has the struct tag
in |
334 // the form of `gae:"$<key>[,<default>]?"`. | 321 // the form of `gae:"$<key>[,<default>]?"`. |
335 // | 322 // |
336 // Supported metadata types are: | 323 // Supported metadata types are: |
337 // int64 - may have default (ascii encoded base-10) | 324 // int64 - may have default (ascii encoded base-10) |
338 // string - may have default | 325 // string - may have default |
339 // Toggle - MUST have default ("true" or "false") | 326 // Toggle - MUST have default ("true" or "false") |
340 // Key - NO default allowed | 327 // Key - NO default allowed |
341 // | 328 // |
342 // Struct fields of type Toggle (which is an Auto/On/Off) require you to | 329 // Struct fields of type Toggle (which is an Auto/On/Off) require you to |
(...skipping 12 matching lines...) Expand all Loading... |
355 // // val == 10 | 342 // // val == 10 |
356 // // err == nil | 343 // // err == nil |
357 // | 344 // |
358 // type MyStruct struct { | 345 // type MyStruct struct { |
359 // TFlag Toggle `gae:"$flag1,true"` // defaults to true | 346 // TFlag Toggle `gae:"$flag1,true"` // defaults to true |
360 // FFlag Toggle `gae:"$flag2,false"` // defaults to false | 347 // FFlag Toggle `gae:"$flag2,false"` // defaults to false |
361 // // BadFlag Toggle `gae:"$flag3"` // ILLEGAL | 348 // // BadFlag Toggle `gae:"$flag3"` // ILLEGAL |
362 // } | 349 // } |
363 GetMeta(key string) (interface{}, error) | 350 GetMeta(key string) (interface{}, error) |
364 | 351 |
| 352 // GetMetaDefault is GetMeta, but with a default. |
| 353 // |
| 354 // If the metadata key is not available, or its type doesn't equal the |
| 355 // homogenized type of dflt, then dflt will be returned. |
| 356 // |
| 357 // Type homogenization: |
| 358 // signed integer types -> int64 |
| 359 // bool -> Toggle fields (bool) |
| 360 // |
| 361 // Example: |
| 362 // pls.GetMetaDefault("foo", 100).(int64) |
| 363 GetMetaDefault(key string, dflt interface{}) interface{} |
| 364 } |
| 365 |
| 366 // PropertyLoadSaver may be implemented by a user type, and Interface will |
| 367 // use this interface to serialize the type instead of trying to automatically |
| 368 // create a serialization codec for it with helper.GetPLS. |
| 369 type PropertyLoadSaver interface { |
| 370 // Load takes the values from the given map and attempts to save them in
to |
| 371 // the underlying object (usually a struct or a PropertyMap). If a fatal |
| 372 // error occurs, it's returned via error. If non-fatal conversion errors |
| 373 // occur, error will be a MultiError containing one or more ErrFieldMism
atch |
| 374 // objects. |
| 375 Load(PropertyMap) error |
| 376 |
| 377 // Save returns the current property as a PropertyMap. if withMeta is tr
ue, |
| 378 // then the PropertyMap contains all the metadata (e.g. '$meta' fields) |
| 379 // which was held by this PropertyLoadSaver. |
| 380 Save(withMeta bool) (PropertyMap, error) |
| 381 |
| 382 MetaGetter |
| 383 |
365 // SetMeta allows you to set the current value of the meta-keyed field. | 384 // SetMeta allows you to set the current value of the meta-keyed field. |
366 SetMeta(key string, val interface{}) error | 385 SetMeta(key string, val interface{}) error |
367 | 386 |
368 // Problem indicates that this PLS has a fatal problem. Usually this is | 387 // Problem indicates that this PLS has a fatal problem. Usually this is |
369 // set when the underlying struct has recursion, invalid field types, ne
sted | 388 // set when the underlying struct has recursion, invalid field types, ne
sted |
370 // slices, etc. | 389 // slices, etc. |
371 Problem() error | 390 Problem() error |
372 } | 391 } |
373 | 392 |
374 // PropertyMap represents the contents of a datastore entity in a generic way. | 393 // PropertyMap represents the contents of a datastore entity in a generic way. |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
428 v, ok := pm["$"+key] | 447 v, ok := pm["$"+key] |
429 if !ok || len(v) == 0 { | 448 if !ok || len(v) == 0 { |
430 return nil, ErrMetaFieldUnset | 449 return nil, ErrMetaFieldUnset |
431 } | 450 } |
432 if len(v) > 1 { | 451 if len(v) > 1 { |
433 return nil, errors.New("gae: too many values for Meta key") | 452 return nil, errors.New("gae: too many values for Meta key") |
434 } | 453 } |
435 return v[0].Value(), nil | 454 return v[0].Value(), nil |
436 } | 455 } |
437 | 456 |
| 457 func (pm PropertyMap) GetMetaDefault(key string, dflt interface{}) interface{} { |
| 458 return GetMetaDefaultImpl(pm.GetMeta, key, dflt) |
| 459 } |
| 460 |
438 // SetMeta implements PropertyLoadSaver.SetMeta. It will only return an error | 461 // SetMeta implements PropertyLoadSaver.SetMeta. It will only return an error |
439 // if `val` has an invalid type (e.g. not one supported by Property). | 462 // if `val` has an invalid type (e.g. not one supported by Property). |
440 func (pm PropertyMap) SetMeta(key string, val interface{}) error { | 463 func (pm PropertyMap) SetMeta(key string, val interface{}) error { |
441 prop := Property{} | 464 prop := Property{} |
442 if err := prop.SetValue(val, NoIndex); err != nil { | 465 if err := prop.SetValue(val, NoIndex); err != nil { |
443 return err | 466 return err |
444 } | 467 } |
445 pm["$"+key] = []Property{prop} | 468 pm["$"+key] = []Property{prop} |
446 return nil | 469 return nil |
447 } | 470 } |
448 | 471 |
449 // Problem implements PropertyLoadSaver.Problem. It ALWAYS returns nil. | 472 // Problem implements PropertyLoadSaver.Problem. It ALWAYS returns nil. |
450 func (pm PropertyMap) Problem() error { | 473 func (pm PropertyMap) Problem() error { |
451 return nil | 474 return nil |
452 } | 475 } |
| 476 |
| 477 // GetMetaDefaultImpl is the implementation of PropertyLoadSaver.GetMetaDefault. |
| 478 // |
| 479 // It takes the normal GetMeta function, the key and the default, and returns |
| 480 // the value according to PropertyLoadSaver.GetMetaDefault. |
| 481 func GetMetaDefaultImpl(gm func(string) (interface{}, error), key string, dflt i
nterface{}) interface{} { |
| 482 cur, err := gm(key) |
| 483 if err != nil { |
| 484 return dflt |
| 485 } |
| 486 dflt, typ := UpconvertUnderlyingType(dflt, reflect.TypeOf(dflt)) |
| 487 if reflect.TypeOf(cur) != typ { |
| 488 return dflt |
| 489 } |
| 490 return cur |
| 491 } |
OLD | NEW |