| 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 "fmt" | 8 "fmt" |
| 9 "reflect" | 9 "reflect" |
| 10 | 10 |
| 11 "github.com/luci/luci-go/common/errors" | 11 "github.com/luci/luci-go/common/errors" |
| 12 ) | 12 ) |
| 13 | 13 |
| 14 type multiArgType struct { | 14 type multiArgType struct { |
| 15 valid bool | 15 valid bool |
| 16 | 16 |
| 17 » getKey func(aid, ns string, slot reflect.Value) (*Key, error) | 17 » getKey func(aid, ns string, slot reflect.Value) (*Key, error) |
| 18 » getPM func(slot reflect.Value) (PropertyMap, error) | 18 » getPM func(slot reflect.Value) (PropertyMap, error) |
| 19 » setPM func(slot reflect.Value, pm PropertyMap) error | 19 » getMetaPM func(slot reflect.Value) PropertyMap |
| 20 » setKey func(slot reflect.Value, k *Key) | 20 » setPM func(slot reflect.Value, pm PropertyMap) error |
| 21 » newElem func() reflect.Value | 21 » setKey func(slot reflect.Value, k *Key) |
| 22 » newElem func() reflect.Value |
| 22 } | 23 } |
| 23 | 24 |
| 24 func (mat *multiArgType) GetKeysPMs(aid, ns string, slice reflect.Value) ([]*Key
, []PropertyMap, error) { | 25 func (mat *multiArgType) GetKeysPMs(aid, ns string, slice reflect.Value, meta bo
ol) ([]*Key, []PropertyMap, error) { |
| 25 retKey := make([]*Key, slice.Len()) | 26 retKey := make([]*Key, slice.Len()) |
| 26 retPM := make([]PropertyMap, slice.Len()) | 27 retPM := make([]PropertyMap, slice.Len()) |
| 28 getter := mat.getPM |
| 29 if meta { |
| 30 getter = func(slot reflect.Value) (PropertyMap, error) { |
| 31 return mat.getMetaPM(slot), nil |
| 32 } |
| 33 } |
| 27 lme := errors.NewLazyMultiError(len(retKey)) | 34 lme := errors.NewLazyMultiError(len(retKey)) |
| 28 for i := range retKey { | 35 for i := range retKey { |
| 29 key, err := mat.getKey(aid, ns, slice.Index(i)) | 36 key, err := mat.getKey(aid, ns, slice.Index(i)) |
| 30 if !lme.Assign(i, err) { | 37 if !lme.Assign(i, err) { |
| 31 retKey[i] = key | 38 retKey[i] = key |
| 32 » » » pm, err := mat.getPM(slice.Index(i)) | 39 » » » pm, err := getter(slice.Index(i)) |
| 33 if !lme.Assign(i, err) { | 40 if !lme.Assign(i, err) { |
| 34 retPM[i] = pm | 41 retPM[i] = pm |
| 35 } | 42 } |
| 36 } | 43 } |
| 37 } | 44 } |
| 38 return retKey, retPM, lme.Get() | 45 return retKey, retPM, lme.Get() |
| 39 } | 46 } |
| 40 | 47 |
| 41 // parseMultiArg checks that v has type []S, []*S, []I, []P or []*P, for some | 48 // parseMultiArg checks that v has type []S, []*S, []I, []P or []*P, for some |
| 42 // struct type S, for some interface type I, or some non-interface non-pointer | 49 // struct type S, for some interface type I, or some non-interface non-pointer |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 83 func multiArgTypePLS(et reflect.Type) multiArgType { | 90 func multiArgTypePLS(et reflect.Type) multiArgType { |
| 84 ret := multiArgType{ | 91 ret := multiArgType{ |
| 85 valid: true, | 92 valid: true, |
| 86 | 93 |
| 87 getKey: func(aid, ns string, slot reflect.Value) (*Key, error) { | 94 getKey: func(aid, ns string, slot reflect.Value) (*Key, error) { |
| 88 return newKeyObjErr(aid, ns, slot.Addr().Interface()) | 95 return newKeyObjErr(aid, ns, slot.Addr().Interface()) |
| 89 }, | 96 }, |
| 90 getPM: func(slot reflect.Value) (PropertyMap, error) { | 97 getPM: func(slot reflect.Value) (PropertyMap, error) { |
| 91 return slot.Addr().Interface().(PropertyLoadSaver).Save(
true) | 98 return slot.Addr().Interface().(PropertyLoadSaver).Save(
true) |
| 92 }, | 99 }, |
| 100 getMetaPM: func(slot reflect.Value) PropertyMap { |
| 101 return slot.Addr().Interface().(PropertyLoadSaver).GetAl
lMeta() |
| 102 }, |
| 93 setPM: func(slot reflect.Value, pm PropertyMap) error { | 103 setPM: func(slot reflect.Value, pm PropertyMap) error { |
| 94 return slot.Addr().Interface().(PropertyLoadSaver).Load(
pm) | 104 return slot.Addr().Interface().(PropertyLoadSaver).Load(
pm) |
| 95 }, | 105 }, |
| 96 setKey: func(slot reflect.Value, k *Key) { | 106 setKey: func(slot reflect.Value, k *Key) { |
| 97 setKey(slot.Addr().Interface(), k) | 107 setKey(slot.Addr().Interface(), k) |
| 98 }, | 108 }, |
| 99 } | 109 } |
| 100 if et.Kind() == reflect.Map { | 110 if et.Kind() == reflect.Map { |
| 101 ret.newElem = func() reflect.Value { | 111 ret.newElem = func() reflect.Value { |
| 102 // Create a *map so that way slot.Addr() works above whe
n this is | 112 // Create a *map so that way slot.Addr() works above whe
n this is |
| (...skipping 16 matching lines...) Expand all Loading... |
| 119 func multiArgTypePLSPtr(et reflect.Type) multiArgType { | 129 func multiArgTypePLSPtr(et reflect.Type) multiArgType { |
| 120 ret := multiArgType{ | 130 ret := multiArgType{ |
| 121 valid: true, | 131 valid: true, |
| 122 | 132 |
| 123 getKey: func(aid, ns string, slot reflect.Value) (*Key, error) { | 133 getKey: func(aid, ns string, slot reflect.Value) (*Key, error) { |
| 124 return newKeyObjErr(aid, ns, slot.Interface()) | 134 return newKeyObjErr(aid, ns, slot.Interface()) |
| 125 }, | 135 }, |
| 126 getPM: func(slot reflect.Value) (PropertyMap, error) { | 136 getPM: func(slot reflect.Value) (PropertyMap, error) { |
| 127 return slot.Interface().(PropertyLoadSaver).Save(true) | 137 return slot.Interface().(PropertyLoadSaver).Save(true) |
| 128 }, | 138 }, |
| 139 getMetaPM: func(slot reflect.Value) PropertyMap { |
| 140 return slot.Interface().(PropertyLoadSaver).GetAllMeta() |
| 141 }, |
| 129 setPM: func(slot reflect.Value, pm PropertyMap) error { | 142 setPM: func(slot reflect.Value, pm PropertyMap) error { |
| 130 return slot.Interface().(PropertyLoadSaver).Load(pm) | 143 return slot.Interface().(PropertyLoadSaver).Load(pm) |
| 131 }, | 144 }, |
| 132 setKey: func(slot reflect.Value, k *Key) { | 145 setKey: func(slot reflect.Value, k *Key) { |
| 133 setKey(slot.Interface(), k) | 146 setKey(slot.Interface(), k) |
| 134 }, | 147 }, |
| 135 } | 148 } |
| 136 if et.Kind() == reflect.Map { | 149 if et.Kind() == reflect.Map { |
| 137 ret.newElem = func() reflect.Value { | 150 ret.newElem = func() reflect.Value { |
| 138 ptr := reflect.New(et) | 151 ptr := reflect.New(et) |
| (...skipping 17 matching lines...) Expand all Loading... |
| 156 } | 169 } |
| 157 return multiArgType{ | 170 return multiArgType{ |
| 158 valid: true, | 171 valid: true, |
| 159 | 172 |
| 160 getKey: func(aid, ns string, slot reflect.Value) (*Key, error) { | 173 getKey: func(aid, ns string, slot reflect.Value) (*Key, error) { |
| 161 return newKeyObjErr(aid, ns, toPLS(slot)) | 174 return newKeyObjErr(aid, ns, toPLS(slot)) |
| 162 }, | 175 }, |
| 163 getPM: func(slot reflect.Value) (PropertyMap, error) { | 176 getPM: func(slot reflect.Value) (PropertyMap, error) { |
| 164 return toPLS(slot).(PropertyLoadSaver).Save(true) | 177 return toPLS(slot).(PropertyLoadSaver).Save(true) |
| 165 }, | 178 }, |
| 179 getMetaPM: func(slot reflect.Value) PropertyMap { |
| 180 return toPLS(slot).(PropertyLoadSaver).GetAllMeta() |
| 181 }, |
| 166 setPM: func(slot reflect.Value, pm PropertyMap) error { | 182 setPM: func(slot reflect.Value, pm PropertyMap) error { |
| 167 return toPLS(slot).(PropertyLoadSaver).Load(pm) | 183 return toPLS(slot).(PropertyLoadSaver).Load(pm) |
| 168 }, | 184 }, |
| 169 setKey: func(slot reflect.Value, k *Key) { | 185 setKey: func(slot reflect.Value, k *Key) { |
| 170 setKey(toPLS(slot), k) | 186 setKey(toPLS(slot), k) |
| 171 }, | 187 }, |
| 172 newElem: func() reflect.Value { | 188 newElem: func() reflect.Value { |
| 173 return reflect.New(et).Elem() | 189 return reflect.New(et).Elem() |
| 174 }, | 190 }, |
| 175 } | 191 } |
| (...skipping 10 matching lines...) Expand all Loading... |
| 186 } | 202 } |
| 187 return multiArgType{ | 203 return multiArgType{ |
| 188 valid: true, | 204 valid: true, |
| 189 | 205 |
| 190 getKey: func(aid, ns string, slot reflect.Value) (*Key, error) { | 206 getKey: func(aid, ns string, slot reflect.Value) (*Key, error) { |
| 191 return newKeyObjErr(aid, ns, toPLS(slot)) | 207 return newKeyObjErr(aid, ns, toPLS(slot)) |
| 192 }, | 208 }, |
| 193 getPM: func(slot reflect.Value) (PropertyMap, error) { | 209 getPM: func(slot reflect.Value) (PropertyMap, error) { |
| 194 return toPLS(slot).(PropertyLoadSaver).Save(true) | 210 return toPLS(slot).(PropertyLoadSaver).Save(true) |
| 195 }, | 211 }, |
| 212 getMetaPM: func(slot reflect.Value) PropertyMap { |
| 213 return toPLS(slot).(PropertyLoadSaver).GetAllMeta() |
| 214 }, |
| 196 setPM: func(slot reflect.Value, pm PropertyMap) error { | 215 setPM: func(slot reflect.Value, pm PropertyMap) error { |
| 197 return toPLS(slot).(PropertyLoadSaver).Load(pm) | 216 return toPLS(slot).(PropertyLoadSaver).Load(pm) |
| 198 }, | 217 }, |
| 199 setKey: func(slot reflect.Value, k *Key) { | 218 setKey: func(slot reflect.Value, k *Key) { |
| 200 setKey(toPLS(slot), k) | 219 setKey(toPLS(slot), k) |
| 201 }, | 220 }, |
| 202 newElem: func() reflect.Value { | 221 newElem: func() reflect.Value { |
| 203 return reflect.New(et) | 222 return reflect.New(et) |
| 204 }, | 223 }, |
| 205 } | 224 } |
| 206 } | 225 } |
| 207 | 226 |
| 208 // multiArgTypeInterface == []I | 227 // multiArgTypeInterface == []I |
| 209 func multiArgTypeInterface() multiArgType { | 228 func multiArgTypeInterface() multiArgType { |
| 210 return multiArgType{ | 229 return multiArgType{ |
| 211 valid: true, | 230 valid: true, |
| 212 | 231 |
| 213 getKey: func(aid, ns string, slot reflect.Value) (*Key, error) { | 232 getKey: func(aid, ns string, slot reflect.Value) (*Key, error) { |
| 214 return newKeyObjErr(aid, ns, slot.Elem().Interface()) | 233 return newKeyObjErr(aid, ns, slot.Elem().Interface()) |
| 215 }, | 234 }, |
| 216 getPM: func(slot reflect.Value) (PropertyMap, error) { | 235 getPM: func(slot reflect.Value) (PropertyMap, error) { |
| 217 pls := mkPLS(slot.Elem().Interface()) | 236 pls := mkPLS(slot.Elem().Interface()) |
| 218 return pls.Save(true) | 237 return pls.Save(true) |
| 219 }, | 238 }, |
| 239 getMetaPM: func(slot reflect.Value) PropertyMap { |
| 240 pls := mkPLS(slot.Elem().Interface()) |
| 241 return pls.GetAllMeta() |
| 242 }, |
| 220 setPM: func(slot reflect.Value, pm PropertyMap) error { | 243 setPM: func(slot reflect.Value, pm PropertyMap) error { |
| 221 pls := mkPLS(slot.Elem().Interface()) | 244 pls := mkPLS(slot.Elem().Interface()) |
| 222 return pls.Load(pm) | 245 return pls.Load(pm) |
| 223 }, | 246 }, |
| 224 setKey: func(slot reflect.Value, k *Key) { | 247 setKey: func(slot reflect.Value, k *Key) { |
| 225 setKey(slot.Elem().Interface(), k) | 248 setKey(slot.Elem().Interface(), k) |
| 226 }, | 249 }, |
| 227 } | 250 } |
| 228 } | 251 } |
| 229 | 252 |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 262 _ = pls.SetMeta("parent", key.Parent()) | 285 _ = pls.SetMeta("parent", key.Parent()) |
| 263 } | 286 } |
| 264 } | 287 } |
| 265 | 288 |
| 266 func mkPLS(o interface{}) PropertyLoadSaver { | 289 func mkPLS(o interface{}) PropertyLoadSaver { |
| 267 if pls, ok := o.(PropertyLoadSaver); ok { | 290 if pls, ok := o.(PropertyLoadSaver); ok { |
| 268 return pls | 291 return pls |
| 269 } | 292 } |
| 270 return GetPLS(o) | 293 return GetPLS(o) |
| 271 } | 294 } |
| OLD | NEW |