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())) }
// cat is a convenience method for concatenating anything with an underlying // byte representation into a single []byte. func cat(bytethings ...interface{}) []byte { err := error(nil) buf := &bytes.Buffer{} for _, thing := range bytethings { switch x := thing.(type) { case int64: _, err = cmpbin.WriteInt(buf, x) case int: _, err = cmpbin.WriteInt(buf, int64(x)) case uint64: _, err = cmpbin.WriteUint(buf, x) case uint: _, err = cmpbin.WriteUint(buf, uint64(x)) case float64: _, err = cmpbin.WriteFloat64(buf, x) case byte: err = buf.WriteByte(x) case ds.PropertyType: err = buf.WriteByte(byte(x)) case string: _, err = cmpbin.WriteString(buf, x) case []byte: _, err = buf.Write(x) case time.Time: err = serialize.WriteTime(buf, x) case *ds.Key: err = serialize.WriteKey(buf, serialize.WithoutContext, x) case *ds.IndexDefinition: err = serialize.WriteIndexDefinition(buf, *x) case ds.Property: err = serialize.WriteProperty(buf, serialize.WithoutContext, x) default: panic(fmt.Errorf("I don't know how to deal with %T: %#v", thing, thing)) } die(err) } ret := buf.Bytes() if ret == nil { ret = []byte{} } return ret }