// This kind of iterator expects to last more than 60s, which is when a regular datastore // iterator will timeout (it thinks its view of the world is too stale) // Instead, we just grab all the keys up front, and than instantiate them one at a time. func (db FlightDB) LongIterWith(q *datastore.Query, flightProcFunc func(*f.Flight)) error { keys, err := q.KeysOnly().GetAll(db.C, nil) if err != nil { return err } for _, key := range keys { blob := f.FrozenFlight{} if err := datastore.Get(db.C, key, &blob); err != nil { return err } if flight, err := blob.Thaw(); err != nil { return err } else { //flight.EnterUTC,flight.LeaveUTC = flight.Track.TimesInBox(sfo.KBoxSnarfingCatchment) flight.SetDatastoreKey(key.Encode()) flightProcFunc(flight) } } return nil }
func GetAllKeys(c appengine.Context, q *ds.Query, limit int) ([]*ds.Key, ds.Cursor, bool, error) { it := q.KeysOnly().Limit(limit + 1).Run(c) keys := make([]*ds.Key, 0, limit) hasMore := true for i := 0; i < limit; i++ { key, err := it.Next(nil) if err == ds.Done { hasMore = false break } else if err != nil { return nil, ds.Cursor{}, false, err } keys = append(keys, key) } cursor, _ := it.Cursor() if hasMore { if _, err := it.Next(nil); err != nil { hasMore = false } } return keys, cursor, hasMore, nil }
func (db FlightDB) countByQuery(q *datastore.Query) (int, error) { q2 := q.KeysOnly() keys, err := q2.GetAll(db.C, nil) if err != nil { return 0, err } return len(keys), nil }
// USE: keys,ok := db.SelectKeys(qry) func (db *Manager) SelectKeys(qry *datastore.Query) ([]string, bool) { recs := new(interface{}) keys, err := qry.KeysOnly().GetAll(db.Context, recs) skeys := []string{} if err == nil { for k := range keys { skeys = append(skeys, keys[k].StringID()) } } return skeys, err == nil }
func GetPage(c appengine.Context, query *datastore.Query, limit int, keysOnly bool, dst interface{}) (*Page, error) { var dv reflect.Value var mat multiArgType var elemType reflect.Type if !keysOnly { dv = reflect.ValueOf(dst) if dv.Kind() != reflect.Ptr || dv.IsNil() { return nil, datastore.ErrInvalidEntityType } dv = dv.Elem() mat, elemType = checkMultiArg(dv) if mat == multiArgTypeInvalid || mat == multiArgTypeInterface { return nil, datastore.ErrInvalidEntityType } } var keys []*datastore.Key var cursor datastore.Cursor query = query.Limit(limit + 1) if keysOnly { query = query.KeysOnly() } t := query.Run(c) more := true for i := 0; i < limit; i++ { var ev reflect.Value if !keysOnly { ev = reflect.New(elemType) } k, err := t.Next(ev.Interface()) if err == datastore.Done { more = false break } if err != nil { return nil, err } if !keysOnly { if mat != multiArgTypeStructPtr { ev = ev.Elem() } dv.Set(reflect.Append(dv, ev)) } keys = append(keys, k) } if more { var err error cursor, err = t.Cursor() if err != nil { return nil, err } var ei interface{} if !keysOnly { ei = reflect.New(elemType).Interface() } _, err = t.Next(ei) if err == datastore.Done { more = false } } return &Page{ Keys: keys, Start: cursor, More: more, }, nil }