1package gocb
2
3import (
4	"fmt"
5	"net/url"
6	"strconv"
7	"strings"
8)
9
10// SpatialQuery represents a pending spatial query.
11type SpatialQuery struct {
12	ddoc    string
13	name    string
14	options url.Values
15}
16
17// Stale specifies the level of consistency required for this query.
18func (vq *SpatialQuery) Stale(stale StaleMode) *SpatialQuery {
19	if stale == Before {
20		vq.options.Set("stale", "false")
21	} else if stale == None {
22		vq.options.Set("stale", "ok")
23	} else if stale == After {
24		vq.options.Set("stale", "update_after")
25	} else {
26		panic("Unexpected stale option")
27	}
28	return vq
29}
30
31// Skip specifies how many results to skip at the beginning of the result list.
32func (vq *SpatialQuery) Skip(num uint) *SpatialQuery {
33	vq.options.Set("skip", strconv.FormatUint(uint64(num), 10))
34	return vq
35}
36
37// Limit specifies a limit on the number of results to return.
38func (vq *SpatialQuery) Limit(num uint) *SpatialQuery {
39	vq.options.Set("limit", strconv.FormatUint(uint64(num), 10))
40	return vq
41}
42
43// Bbox specifies the bounding region to use for the spatial query.
44func (vq *SpatialQuery) Bbox(bounds []float64) *SpatialQuery {
45	if len(bounds) == 4 {
46		vq.options.Set("bbox", fmt.Sprintf("%f,%f,%f,%f", bounds[0], bounds[1], bounds[2], bounds[3]))
47	} else {
48		vq.options.Del("bbox")
49	}
50	return vq
51}
52
53// Development specifies whether to query the production or development design document.
54func (vq *SpatialQuery) Development(val bool) *SpatialQuery {
55	if val {
56		if !strings.HasPrefix(vq.ddoc, "dev_") {
57			vq.ddoc = "dev_" + vq.ddoc
58		}
59	} else {
60		vq.ddoc = strings.TrimPrefix(vq.ddoc, "dev_")
61	}
62	return vq
63}
64
65// Custom allows specifying custom query options.
66func (vq *SpatialQuery) Custom(name, value string) *SpatialQuery {
67	vq.options.Set(name, value)
68	return vq
69}
70
71func (vq *SpatialQuery) getInfo() (string, string, url.Values, error) {
72	return vq.ddoc, vq.name, vq.options, nil
73}
74
75// NewSpatialQuery creates a new SpatialQuery object from a design document and view name.
76func NewSpatialQuery(ddoc, name string) *SpatialQuery {
77	return &SpatialQuery{
78		ddoc:    ddoc,
79		name:    name,
80		options: url.Values{},
81	}
82}
83