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 |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
158 fq, err := q.Finalize() | 158 fq, err := q.Finalize() |
159 if err != nil { | 159 if err != nil { |
160 return 0, err | 160 return 0, err |
161 } | 161 } |
162 return d.RawInterface.Count(fq) | 162 return d.RawInterface.Count(fq) |
163 } | 163 } |
164 | 164 |
165 func (d *datastoreImpl) GetAll(q *Query, dst interface{}) error { | 165 func (d *datastoreImpl) GetAll(q *Query, dst interface{}) error { |
166 v := reflect.ValueOf(dst) | 166 v := reflect.ValueOf(dst) |
167 if v.Kind() != reflect.Ptr { | 167 if v.Kind() != reflect.Ptr { |
168 » » return fmt.Errorf("invalid GetAll dst: must have a ptr-to-slice:
%T", dst) | 168 » » panic(fmt.Errorf("invalid GetAll dst: must have a ptr-to-slice:
%T", dst)) |
169 } | 169 } |
170 if !v.IsValid() || v.IsNil() { | 170 if !v.IsValid() || v.IsNil() { |
171 » » return errors.New("invalid GetAll dst: <nil>") | 171 » » panic(errors.New("invalid GetAll dst: <nil>")) |
172 } | 172 } |
173 | 173 |
174 if keys, ok := dst.(*[]*Key); ok { | 174 if keys, ok := dst.(*[]*Key); ok { |
175 fq, err := q.KeysOnly(true).Finalize() | 175 fq, err := q.KeysOnly(true).Finalize() |
176 if err != nil { | 176 if err != nil { |
177 return err | 177 return err |
178 } | 178 } |
179 | 179 |
180 return d.RawInterface.Run(fq, func(k *Key, _ PropertyMap, _ Curs
orCB) error { | 180 return d.RawInterface.Run(fq, func(k *Key, _ PropertyMap, _ Curs
orCB) error { |
181 *keys = append(*keys, k) | 181 *keys = append(*keys, k) |
182 return nil | 182 return nil |
183 }) | 183 }) |
184 } | 184 } |
185 fq, err := q.Finalize() | 185 fq, err := q.Finalize() |
186 if err != nil { | 186 if err != nil { |
187 return err | 187 return err |
188 } | 188 } |
189 | 189 |
190 slice := v.Elem() | 190 slice := v.Elem() |
191 mat := parseMultiArg(slice.Type()) | 191 mat := parseMultiArg(slice.Type()) |
192 if mat.newElem == nil { | 192 if mat.newElem == nil { |
193 » » return fmt.Errorf("invalid GetAll input type: %T", dst) | 193 » » panic(fmt.Errorf("invalid GetAll dst (non-concrete element type)
: %T", dst)) |
194 } | 194 } |
195 | 195 |
196 errs := map[int]error{} | 196 errs := map[int]error{} |
197 i := 0 | 197 i := 0 |
198 err = d.RawInterface.Run(fq, func(k *Key, pm PropertyMap, _ CursorCB) er
ror { | 198 err = d.RawInterface.Run(fq, func(k *Key, pm PropertyMap, _ CursorCB) er
ror { |
199 slice.Set(reflect.Append(slice, mat.newElem())) | 199 slice.Set(reflect.Append(slice, mat.newElem())) |
200 itm := slice.Index(i) | 200 itm := slice.Index(i) |
201 mat.setKey(itm, k) | 201 mat.setKey(itm, k) |
202 err := mat.setPM(itm, pm) | 202 err := mat.setPM(itm, pm) |
203 if err != nil { | 203 if err != nil { |
204 errs[i] = err | 204 errs[i] = err |
205 } | 205 } |
206 i++ | 206 i++ |
207 return nil | 207 return nil |
208 }) | 208 }) |
209 if err == nil { | 209 if err == nil { |
210 if len(errs) > 0 { | 210 if len(errs) > 0 { |
211 me := make(errors.MultiError, slice.Len()) | 211 me := make(errors.MultiError, slice.Len()) |
212 for i, e := range errs { | 212 for i, e := range errs { |
213 me[i] = e | 213 me[i] = e |
214 } | 214 } |
215 err = me | 215 err = me |
216 } | 216 } |
217 } | 217 } |
218 return err | 218 return err |
219 } | 219 } |
220 | 220 |
221 func isOkType(v reflect.Type) bool { | 221 func isOkType(t reflect.Type) error { |
222 » if v == typeOfKey { | 222 » if t == nil { |
223 » » return false | 223 » » return errors.New("no type information") |
224 } | 224 } |
225 » if v.Implements(typeOfPropertyLoadSaver) { | 225 » if t.Implements(typeOfPropertyLoadSaver) { |
226 » » return true | 226 » » return nil |
227 } | 227 } |
228 » if v.Kind() == reflect.Ptr && v.Elem().Kind() == reflect.Struct { | 228 » if t == typeOfKey { |
229 » » return true | 229 » » return errors.New("not user datatype") |
230 } | 230 } |
231 » return false | 231 » if t.Kind() != reflect.Ptr { |
| 232 » » return errors.New("not a pointer") |
| 233 » } |
| 234 » if t.Elem().Kind() != reflect.Struct { |
| 235 » » return errors.New("does not point to a struct") |
| 236 » } |
| 237 » return nil |
232 } | 238 } |
233 | 239 |
234 func (d *datastoreImpl) ExistsMulti(keys []*Key) ([]bool, error) { | 240 func (d *datastoreImpl) ExistsMulti(keys []*Key) ([]bool, error) { |
235 lme := errors.NewLazyMultiError(len(keys)) | 241 lme := errors.NewLazyMultiError(len(keys)) |
236 ret := make([]bool, len(keys)) | 242 ret := make([]bool, len(keys)) |
237 i := 0 | 243 i := 0 |
238 err := d.RawInterface.GetMulti(keys, nil, func(_ PropertyMap, err error)
error { | 244 err := d.RawInterface.GetMulti(keys, nil, func(_ PropertyMap, err error)
error { |
239 if err == nil { | 245 if err == nil { |
240 ret[i] = true | 246 ret[i] = true |
241 } else if err != ErrNoSuchEntity { | 247 } else if err != ErrNoSuchEntity { |
242 lme.Assign(i, err) | 248 lme.Assign(i, err) |
243 } | 249 } |
244 i++ | 250 i++ |
245 return nil | 251 return nil |
246 }) | 252 }) |
247 if err != nil { | 253 if err != nil { |
248 return ret, err | 254 return ret, err |
249 } | 255 } |
250 return ret, lme.Get() | 256 return ret, lme.Get() |
251 } | 257 } |
252 | 258 |
253 func (d *datastoreImpl) Exists(k *Key) (bool, error) { | 259 func (d *datastoreImpl) Exists(k *Key) (bool, error) { |
254 ret, err := d.ExistsMulti([]*Key{k}) | 260 ret, err := d.ExistsMulti([]*Key{k}) |
255 return ret[0], errors.SingleError(err) | 261 return ret[0], errors.SingleError(err) |
256 } | 262 } |
257 | 263 |
258 func (d *datastoreImpl) Get(dst interface{}) (err error) { | 264 func (d *datastoreImpl) Get(dst interface{}) (err error) { |
259 » if !isOkType(reflect.TypeOf(dst)) { | 265 » if err := isOkType(reflect.TypeOf(dst)); err != nil { |
260 » » return fmt.Errorf("invalid Get input type: %T", dst) | 266 » » panic(fmt.Errorf("invalid Get input type (%T): %s", dst, err)) |
261 } | 267 } |
262 return errors.SingleError(d.GetMulti([]interface{}{dst})) | 268 return errors.SingleError(d.GetMulti([]interface{}{dst})) |
263 } | 269 } |
264 | 270 |
265 func (d *datastoreImpl) Put(src interface{}) (err error) { | 271 func (d *datastoreImpl) Put(src interface{}) (err error) { |
266 » if !isOkType(reflect.TypeOf(src)) { | 272 » if err := isOkType(reflect.TypeOf(src)); err != nil { |
267 » » return fmt.Errorf("invalid Put input type: %T", src) | 273 » » panic(fmt.Errorf("invalid Put input type (%T): %s", src, err)) |
268 } | 274 } |
269 return errors.SingleError(d.PutMulti([]interface{}{src})) | 275 return errors.SingleError(d.PutMulti([]interface{}{src})) |
270 } | 276 } |
271 | 277 |
272 func (d *datastoreImpl) Delete(key *Key) (err error) { | 278 func (d *datastoreImpl) Delete(key *Key) (err error) { |
273 return errors.SingleError(d.DeleteMulti([]*Key{key})) | 279 return errors.SingleError(d.DeleteMulti([]*Key{key})) |
274 } | 280 } |
275 | 281 |
276 func (d *datastoreImpl) GetMulti(dst interface{}) error { | 282 func (d *datastoreImpl) GetMulti(dst interface{}) error { |
277 slice := reflect.ValueOf(dst) | 283 slice := reflect.ValueOf(dst) |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
335 err = lme.Get() | 341 err = lme.Get() |
336 if err == nil { | 342 if err == nil { |
337 err = extErr | 343 err = extErr |
338 } | 344 } |
339 return | 345 return |
340 } | 346 } |
341 | 347 |
342 func (d *datastoreImpl) Raw() RawInterface { | 348 func (d *datastoreImpl) Raw() RawInterface { |
343 return d.RawInterface | 349 return d.RawInterface |
344 } | 350 } |
OLD | NEW |