Beispiel #1
0
// DelQuery will delete (from datastore and memcache) all entities of type src that matches q.
// src must be a pointer to a struct type.
func DelQuery(c PersistenceContext, src interface{}, q *datastore.Query) (err error) {
	var dataIds []*datastore.Key
	results := reflect.New(reflect.SliceOf(reflect.TypeOf(src).Elem()))
	dataIds, err = q.GetAll(c, results.Interface())
	if err = FilterOkErrors(err); err != nil {
		return
	}
	memcacheKeys := []string{}
	var el reflect.Value
	resultsSlice := results.Elem()
	for index, dataId := range dataIds {
		el = resultsSlice.Index(index)
		var k key.Key
		if k, err = gaekey.FromGAE(dataId); err != nil {
			return
		}
		el.FieldByName("Id").Set(reflect.ValueOf(k))
		if _, err = MemcacheKeys(c, el.Addr().Interface(), &memcacheKeys); err != nil {
			return
		}
		if err = runProcess(c, el.Addr().Interface(), BeforeDeleteName, nil); err != nil {
			return
		}
	}
	if err = datastore.DeleteMulti(c, dataIds); err != nil {
		return
	}
	for index, _ := range dataIds {
		el = resultsSlice.Index(index)
		if err = runProcess(c, el.Addr().Interface(), AfterDeleteName, nil); err != nil {
			return
		}
	}
	return memcache.Del(c, memcacheKeys...)
}
Beispiel #2
0
func (db FlightDB) lookupByQuery(q *datastore.Query, memKey string) ([]f.Flight, error) {

	if db.Memcache && memKey != "" {
		if flights, found := db.flightsFromShardedMemcache(memKey); found {
			return flights, nil
		}
	}

	fflights := []f.FrozenFlight{}
	//db.C.Infof(" #--- actually going to datastore ...")
	keys, err := q.GetAll(db.C, &fflights)
	if err != nil {
		return nil, err
	}

	flights := []f.Flight{}
	for i, fflight := range fflights {
		if flight, err := fflight.Thaw(); err != nil {
			return nil, err
		} else {
			flight.EnterUTC, flight.LeaveUTC = flight.Track.TimesInBox(sfo.KBoxSnarfingCatchment)
			flight.SetDatastoreKey(keys[i].Encode())
			flights = append(flights, *flight)
		}
	}

	if db.Memcache && memKey != "" {
		db.flightsToShardedMemcache(memKey, flights)
	}

	return flights, nil
}
Beispiel #3
0
func queryPackages(c appengine.Context, cacheKey string, query *datastore.Query) ([]*Package, error) {
	var pkgs []*Package
	item, err := cacheGet(c, cacheKey, &pkgs)
	if err == memcache.ErrCacheMiss {
		keys, err := query.GetAll(c, &pkgs)
		if err != nil {
			return nil, err
		}
		for i := range keys {
			importPath := keys[i].StringID()
			if importPath[0] == '/' {
				// Standard packages start with "/"
				importPath = importPath[1:]
			}
			pkgs[i].ImportPath = importPath
		}
		item.Expiration = time.Hour
		item.Object = pkgs
		if err := cacheSafeSet(c, item); err != nil {
			return nil, err
		}
	} else if err != nil {
		return nil, err
	}
	return pkgs, nil
}
Beispiel #4
0
/* Query the datastore.
 * TODO: Use memcache.
 *
 * @param context for this particular appengine session
 * @param key datastore key for the object to be retrieved
 * @param object the object to be made persistent
 * @param error message to be printed to the log / user in case of error
 * @return a list of keys returned by the query and errors generated by the query (if there are any)
 */
func query(context appengine.Context, query *datastore.Query, objects interface{}, error string) ([]*datastore.Key, os.Error) {
	keys, err := query.GetAll(context, objects)
	if err != nil {
		log.Println(error + err.String())
		return nil, err
	}
	return keys, nil
}
Beispiel #5
0
func (mp person_mapper) MapRows(c appengine.Context, q *datastore.Query, dst interface{}) error {
	if _, ok := dst.(*[]*Person); !ok {
		return errors.New("the parameter is not slice, please check it.")
	}
	dstc := dst.(*[]*Person)
	_, err := q.GetAll(c, dstc)
	if err != nil {
		return err
	}
	return nil
}
Beispiel #6
0
// LoadConfList executes the given query and returns a new ConfList with the given title and
// containing the conferences obtained from the query result.
func LoadConfList(ctx appengine.Context, title string, q *datastore.Query) (*ConfList, error) {
	list := &ConfList{Title: title}

	ks, err := q.GetAll(ctx, &list.Conferences)
	if err != nil {
		return nil, fmt.Errorf("get %q: %v", list.Title, err)
	}
	for i, k := range ks {
		list.Conferences[i].key = k
	}
	return list, nil
}
Beispiel #7
0
// Builds a list of all of the simulations that match a query as SimulationData types
func GetSimulationDataSlice(r *http.Request, q *datastore.Query) ([]models.SimulationData, error) {
	var simulations []models.SimulationData
	var simulationObjs []models.Simulation

	ctx := appengine.NewContext(r)
	simulationKeys, err := q.GetAll(ctx, &simulationObjs)

	if err != nil {
		return simulations, err
	}

	return BuildSimulationDataSlice(ctx, simulationObjs, simulationKeys)
}
Beispiel #8
0
// QueryData returns a datastore.Query.GetAll result and also caches the result
// into memcache.
func QueryData(c appengine.Context, mcKey string, q *datastore.Query, dst interface{}) error {
	err := mcGet(c, mcKey, dst)
	switch err {
	case memcache.ErrCacheMiss:
		if _, err := q.GetAll(c, dst); err != nil {
			return err
		}
		mcSet(c, mcKey, dst)
		return nil
	case nil:
		return nil
	}
	return err
}
Beispiel #9
0
func GetQuery(c PersistenceContext, src interface{}, q *datastore.Query) (err error) {
	srcTyp := reflect.TypeOf(src)
	if srcTyp.Kind() != reflect.Ptr {
		err = errors.Errorf("%+v is not a pointer", src)
		return
	}
	if srcTyp.Elem().Kind() != reflect.Slice {
		err = errors.Errorf("%+v is not a pointer to a slice", src)
		return
	}
	if srcTyp.Elem().Elem().Kind() == reflect.Ptr {
		if srcTyp.Elem().Elem().Elem().Kind() != reflect.Struct {
			err = errors.Errorf("%+v is not a pointer to a slice of struct pointers", src)
			return
		}
	} else if srcTyp.Elem().Elem().Kind() != reflect.Struct {
		err = errors.Errorf("%+v is not a pointer to a slice of structs", src)
		return
	}
	var dataIds []*datastore.Key
	dataIds, err = q.GetAll(c, src)
	if err = FilterOkErrors(err); err != nil {
		return
	}
	srcVal := reflect.ValueOf(src)
	for index, dataId := range dataIds {
		el := srcVal.Elem().Index(index)
		var k key.Key
		if k, err = gaekey.FromGAE(dataId); err != nil {
			return
		}
		if el.Kind() == reflect.Ptr {
			el.Elem().FieldByName("Id").Set(reflect.ValueOf(k))
			if err = runProcess(c, el.Interface(), AfterLoadName, nil); err != nil {
				return
			}
		} else {
			el.FieldByName("Id").Set(reflect.ValueOf(k))
			if err = runProcess(c, el.Addr().Interface(), AfterLoadName, nil); err != nil {
				return
			}
		}
	}
	return
}
Beispiel #10
0
func returnItems(c appengine.Context, q *datastore.Query, w http.ResponseWriter) {
	var orders []Order
	type Item struct {
		Order
		Id string `json:"id"`
	}
	var items []Item
	keys, err := q.GetAll(c, &orders)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	for i, o := range orders {
		items = append(items, Item{Order: o, Id: keys[i].Encode()})
	}
	enc := json.NewEncoder(w)
	enc.Encode(items)
}
Beispiel #11
0
// FindByQuery finds Records handled by this Model.
//
// Returns an array of records as the first argument,
// or an error as the second return argument.
//
// The queryOrFunc argument may be one of:
//
//   *datastore.Query
// The specified query will be used to find records.
//   func(*datastore.Query)
// A new query will be created and the specified function will be
// used to further configure the query.
//
// Example:
//  model := NewModel("people")
//  women, err := model.FindByQuery(func(q *datastore.Query){
//	  q.Filter("sex=", "male")
//  })
//
// Raises events for each record:
//   Model.AfterFind with Args(record)
func (m *Model) FindByQuery(queryOrFunc interface{}) ([]*Record, os.Error) {

	var query *datastore.Query

	if reflect.TypeOf(queryOrFunc).Kind() == reflect.Func {

		// create a new query
		query = m.NewQuery()

		// ask the func to configure the query
		queryOrFunc.(func(*datastore.Query))(query)

	} else {

		// just use the query
		query = queryOrFunc.(*datastore.Query)

	}

	var records []*Record
	keys, err := query.GetAll(m.AppEngineContext(), &records)

	if err == nil {

		// configure each loaded record
		for index, record := range records {

			record.configureRecord(m, keys[index])

			if m.AfterFind.HasCallbacks() {
				m.AfterFind.Trigger(record)
			}

		}

		return records, nil

	}

	return nil, err

}
Beispiel #12
0
/**
 * データストアの単語をすべて削除する
 * ajaxから呼び出すためのAPI
 */
func clear(w http.ResponseWriter, r *http.Request) {
	var c appengine.Context
	var u *user.User
	var keys []*datastore.Key
	var err error
	var query *datastore.Query
	var count int
	var entities []Entity

	c = appengine.NewContext(r)
	u = user.Current(c)
	query = datastore.NewQuery("words").Filter("UserID =", u.ID)
	count, err = query.Count(c)
	Check(c, err)
	entities = make([]Entity, count)
	keys, err = query.GetAll(c, &entities)
	Check(c, err)
	err = datastore.DeleteMulti(c, keys)
	Check(c, err)
}
Beispiel #13
0
/*
 * Get article data
 */
func getArticleData(dbQuery *datastore.Query, MDOutput bool, c appengine.Context) (articleData []ArticleData, err error) {
	var articleDB []*ArticleDB
	_, err = dbQuery.GetAll(c, &articleDB)
	if err != nil {
		return
	}

	articleData = make([]ArticleData, len(articleDB))
	for i := 0; i < len(articleDB); i++ {
		articleData[i].ID = articleDB[i].ID
		articleData[i].Title = articleDB[i].Title
		if MDOutput {
			articleData[i].Content = string(blackfriday.MarkdownCommon(articleDB[i].Content))
		} else {
			articleData[i].Content = string(articleDB[i].Content)
		}
		articleData[i].Date = articleDB[i].Date
	}

	return
}
Beispiel #14
0
/*
 * Get widget data
 */
func getWidgetData(dbQuery *datastore.Query, MDOutput bool, c appengine.Context) (widgetData []WidgetData, err error) {
	var widgetDB []*WidgetDB
	_, err = dbQuery.GetAll(c, &widgetDB)
	if err != nil {
		return
	}

	widgetData = make([]WidgetData, len(widgetDB))
	for i := 0; i < len(widgetDB); i++ {
		widgetData[i].ID = widgetDB[i].ID
		widgetData[i].Title = widgetDB[i].Title
		widgetData[i].Sequence = widgetDB[i].Sequence
		if MDOutput {
			widgetData[i].Content = string(blackfriday.MarkdownCommon(widgetDB[i].Content))
		} else {
			widgetData[i].Content = string(widgetDB[i].Content)
		}
	}

	return
}
Beispiel #15
0
// Builds a list of all of the comments that match a query as CommentData types
func GetCommentDataSlice(r *http.Request, q *datastore.Query) ([]models.CommentData, error) {
	var commentKeys []*datastore.Key
	var commentObjs []models.Comment
	var comments []models.CommentData

	ctx := appengine.NewContext(r)
	commentKeys, err := q.GetAll(ctx, &commentObjs)

	if err != nil {
		return comments, err
	}

	for i, _ := range commentObjs {
		com, err := BuildCommentData(ctx, commentObjs[i], commentKeys[i])
		if err != nil {
			return comments, err
		}
		comments = append(comments, com)
	}

	return comments, nil
}
Beispiel #16
0
func (cdb ComplaintDB) getMaybeCachedComplaintsByQuery(q *datastore.Query, memKey string) ([]*datastore.Key, []types.Complaint, error) {

	if cdb.Memcache && memKey != "" {
		if b, found := BytesFromShardedMemcache(cdb.C, memKey); found == true {
			buf := bytes.NewBuffer(b)
			results := memResults{}
			if err := gob.NewDecoder(buf).Decode(&results); err != nil {
				cdb.C.Errorf("cdb memcache multiget decode: %v", err)
			} else {
				cdb.C.Infof(" #=== Found all items ? Considered cache hit !")
				return results.Keys, results.Vals, nil
			}
		}
	}

	var data = []types.Complaint{}
	//cdb.C.Infof(" #=== Fetching[%s] from DS :(", memKey)

	//tolerantContext := appengine.Timeout(cdb.C, 30*time.Second)  // Default context has a 5s timeout

	keys, err := q.GetAll(cdb.C, &data)
	if err != nil {
		return nil, nil, err
	}

	if cdb.Memcache && memKey != "" {
		var buf bytes.Buffer
		dataToCache := memResults{Keys: keys, Vals: data}
		if err := gob.NewEncoder(&buf).Encode(dataToCache); err != nil {
			cdb.C.Errorf(" #=== cdb error encoding item: %v", err)
		} else {
			b := buf.Bytes()
			BytesToShardedMemcache(cdb.C, memKey, b)
		}
	}

	return keys, data, nil
}
Beispiel #17
0
// USE:  db.Select(qry,&customers)
func (db *Manager) Select(qry *datastore.Query, recs interface{}) bool {
	_, err := qry.GetAll(db.Context, recs)
	return err == nil
}
Beispiel #18
0
// GetAll runs the query and returns all the keys that match the query, as well
// as appending the values to dst, setting the goon key fields of dst, and
// caching the returned data in local memory.
//
// For "keys-only" queries dst can be nil, however if it is not, then GetAll
// appends zero value structs to dst, only setting the goon key fields.
// No data is cached with "keys-only" queries.
//
// See: https://developers.google.com/appengine/docs/go/datastore/reference#Query.GetAll
func (g *Goon) GetAll(q *datastore.Query, dst interface{}) ([]*datastore.Key, error) {
	v := reflect.ValueOf(dst)
	vLenBefore := 0

	if dst != nil {
		if v.Kind() != reflect.Ptr {
			return nil, fmt.Errorf("goon: Expected dst to be a pointer to a slice or nil, got instead: %v", v.Kind())
		}

		v = v.Elem()
		if v.Kind() != reflect.Slice {
			return nil, fmt.Errorf("goon: Expected dst to be a pointer to a slice or nil, got instead: %v", v.Kind())
		}

		vLenBefore = v.Len()
	}

	keys, err := q.GetAll(g.Context, dst)
	if err != nil {
		g.error(err)
		return nil, err
	}
	if dst == nil || len(keys) == 0 {
		return keys, nil
	}

	keysOnly := ((v.Len() - vLenBefore) != len(keys))
	updateCache := !g.inTransaction && !keysOnly

	// If this is a keys-only query, we need to fill the slice with zero value elements
	if keysOnly {
		elemType := v.Type().Elem()
		ptr := false
		if elemType.Kind() == reflect.Ptr {
			elemType = elemType.Elem()
			ptr = true
		}

		if elemType.Kind() != reflect.Struct {
			return keys, fmt.Errorf("goon: Expected struct, got instead: %v", elemType.Kind())
		}

		for i := 0; i < len(keys); i++ {
			ev := reflect.New(elemType)
			if !ptr {
				ev = ev.Elem()
			}

			v.Set(reflect.Append(v, ev))
		}
	}

	if updateCache {
		g.cacheLock.Lock()
		defer g.cacheLock.Unlock()
	}

	for i, k := range keys {
		var e interface{}
		vi := v.Index(vLenBefore + i)
		if vi.Kind() == reflect.Ptr {
			e = vi.Interface()
		} else {
			e = vi.Addr().Interface()
		}

		if err := g.setStructKey(e, k); err != nil {
			return nil, err
		}

		if updateCache {
			// Cache lock is handled before the for loop
			g.cache[memkey(k)] = e
		}
	}

	return keys, nil
}