Ejemplo n.º 1
0
func (q *queryImpl) Order(prop string) ds.Query {
	col := ds.IndexColumn{}
	return q.checkMutateClone(
		func() error {
			// check that first order == first inequality.
			// if order is an equality already, ignore it
			col.Property = strings.TrimSpace(prop)
			if strings.HasPrefix(prop, "-") {
				col.Direction = ds.DESCENDING
				col.Property = strings.TrimSpace(prop[1:])
			} else if strings.HasPrefix(prop, "+") {
				return fmt.Errorf("datastore: invalid order: %q", prop)
			}
			if len(col.Property) == 0 {
				return errors.New("datastore: empty order")
			}
			if len(q.order) == 0 && q.ineqFilter.prop != "" && q.ineqFilter.prop != col.Property {
				return fmt.Errorf(
					"first sort order must match inequality filter: %q v %q",
					prop, q.ineqFilter.prop)
			}
			if q.kind == "" && (col.Property != "__key__" || col.Direction != ds.ASCENDING) {
				return fmt.Errorf("invalid order for kindless query: %#v", col)
			}
			return nil
		},
		func(q *queryImpl) {
			if _, ok := q.eqFilters[col.Property]; ok {
				// skip it if it's an equality filter
				// https://cloud.google.com/appengine/docs/go/datastore/queries#sort_orders_are_ignored_on_properties_with_equality_filters
				return
			}
			for _, order := range q.order {
				if order.Property == col.Property {
					// can't sort by the same order twice
					return
				}
			}
			q.order = append(q.order, col)
		})
}
Ejemplo n.º 2
0
func curs(pairs ...interface{}) queryCursor {
	if len(pairs)%2 != 0 {
		panic("curs() takes only even pairs")
	}
	pre := &bytes.Buffer{}
	cmpbin.WriteUint(pre, uint64(len(pairs)/2))
	post := serialize.Invertible(&bytes.Buffer{})
	for i := 0; i < len(pairs); i += 2 {
		k, v := pairs[i].(string), pairs[i+1]

		col := dsS.IndexColumn{Property: k}

		post.SetInvert(false)
		if k[0] == '-' {
			post.SetInvert(false)
			col.Property = k[1:]
			col.Direction = dsS.DESCENDING
		}
		serialize.WriteIndexColumn(pre, col)
		serialize.WriteProperty(post, serialize.WithoutContext, prop(v))
	}
	return queryCursor(bjoin(pre.Bytes(), post.Bytes()))
}