| 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 | 
|---|