Ejemplo n.º 1
0
func curs(pairs ...interface{}) queryCursor {
	if len(pairs)%2 != 0 {
		panic("curs() takes only even pairs")
	}
	pre := &bytes.Buffer{}
	if _, err := cmpbin.WriteUint(pre, uint64(len(pairs)/2)); err != nil {
		panic(err)
	}
	post := serialize.Invertible(&bytes.Buffer{})
	for i := 0; i < len(pairs); i += 2 {
		k, v := pairs[i].(string), pairs[i+1]

		col, err := dstore.ParseIndexColumn(k)
		if err != nil {
			panic(err)
		}

		post.SetInvert(col.Descending)
		if err := serialize.WriteIndexColumn(pre, col); err != nil {
			panic(err)
		}
		if err := serialize.WriteProperty(post, serialize.WithoutContext, prop(v)); err != nil {
			panic(err)
		}
	}
	return queryCursor(serialize.Join(pre.Bytes(), post.Bytes()))
}
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()))
}
Ejemplo n.º 3
0
func executeQuery(origQ ds.Query, ns string, isTxn bool, idx, head *memStore, cb ds.RawRunCB) error {
	q := origQ.(*queryImpl)

	rq, err := q.reduce(ns, isTxn)
	if err == errQueryDone {
		return nil
	}
	if err != nil {
		return err
	}

	idxs, err := getIndexes(rq, idx)
	if err == errQueryDone {
		return nil
	}
	if err != nil {
		return err
	}

	strategy := pickQueryStrategy(q, rq, cb, head)
	if strategy == nil {
		// e.g. the normalStrategy found that there were NO entities in the current
		// namespace.
		return nil
	}

	offset := q.offset
	limit := q.limit
	hasLimit := q.limitSet && limit >= 0

	cursorPrefix := []byte(nil)
	getCursorFn := func(suffix []byte) func() (ds.Cursor, error) {
		return func() (ds.Cursor, error) {
			if cursorPrefix == nil {
				buf := &bytes.Buffer{}
				_, err := cmpbin.WriteUint(buf, uint64(len(rq.suffixFormat)))
				memoryCorruption(err)

				for _, col := range rq.suffixFormat {
					err := serialize.WriteIndexColumn(buf, col)
					memoryCorruption(err)
				}
				cursorPrefix = buf.Bytes()
			}
			// TODO(riannucci): Do we need to decrement suffix instead of increment
			// if we're sorting by __key__ DESCENDING?
			return queryCursor(bjoin(cursorPrefix, increment(suffix))), nil
		}
	}

	multiIterate(idxs, func(suffix []byte) bool {
		if offset > 0 {
			offset--
			return true
		}
		if hasLimit {
			if limit <= 0 {
				return false
			}
			limit--
		}

		rawData, decodedProps := parseSuffix(ns, rq.suffixFormat, suffix, -1)

		keyProp := decodedProps[len(decodedProps)-1]
		if keyProp.Type() != ds.PTKey {
			impossible(fmt.Errorf("decoded index row doesn't end with a Key: %#v", keyProp))
		}

		return strategy.handle(
			rawData, decodedProps, keyProp.Value().(ds.Key),
			getCursorFn(suffix))
	})

	return nil
}