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