-
Notifications
You must be signed in to change notification settings - Fork 42
/
Copy pathfind.go
128 lines (117 loc) · 4.14 KB
/
find.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
package kivik
import (
"context"
"net/http"
"github.com/go-kivik/kivik/v3/driver"
)
var findNotImplemented = &Error{HTTPStatus: http.StatusNotImplemented, Message: "kivik: driver does not support Find interface"}
// Find executes a query using the new /_find interface. The query must be
// JSON-marshalable to a valid query.
// See http://docs.couchdb.org/en/2.0.0/api/database/find.html#db-find
func (db *DB) Find(ctx context.Context, query interface{}, options ...Options) (*Rows, error) {
if finder, ok := db.driverDB.(driver.OptsFinder); ok {
rowsi, err := finder.Find(ctx, query, mergeOptions(options...))
if err != nil {
return nil, err
}
return newRows(ctx, rowsi), nil
}
// nolint:staticcheck
if finder, ok := db.driverDB.(driver.Finder); ok {
rowsi, err := finder.Find(ctx, query)
if err != nil {
return nil, err
}
return newRows(ctx, rowsi), nil
}
return nil, findNotImplemented
}
// CreateIndex creates an index if it doesn't already exist. ddoc and name may
// be empty, in which case they will be auto-generated. index must be a valid
// index object, as described here:
// http://docs.couchdb.org/en/stable/api/database/find.html#db-index
func (db *DB) CreateIndex(ctx context.Context, ddoc, name string, index interface{}, options ...Options) error {
if finder, ok := db.driverDB.(driver.OptsFinder); ok {
return finder.CreateIndex(ctx, ddoc, name, index, mergeOptions(options...))
}
// nolint:staticcheck
if finder, ok := db.driverDB.(driver.Finder); ok {
return finder.CreateIndex(ctx, ddoc, name, index)
}
return findNotImplemented
}
// DeleteIndex deletes the requested index.
func (db *DB) DeleteIndex(ctx context.Context, ddoc, name string, options ...Options) error {
if finder, ok := db.driverDB.(driver.OptsFinder); ok {
return finder.DeleteIndex(ctx, ddoc, name, mergeOptions(options...))
}
// nolint:staticcheck
if finder, ok := db.driverDB.(driver.Finder); ok {
return finder.DeleteIndex(ctx, ddoc, name)
}
return findNotImplemented
}
// Index is a MonboDB-style index definition.
type Index struct {
DesignDoc string `json:"ddoc,omitempty"`
Name string `json:"name"`
Type string `json:"type"`
Definition interface{} `json:"def"`
}
// GetIndexes returns the indexes defined on the current database.
func (db *DB) GetIndexes(ctx context.Context, options ...Options) ([]Index, error) {
if finder, ok := db.driverDB.(driver.OptsFinder); ok {
dIndexes, err := finder.GetIndexes(ctx, mergeOptions(options...))
indexes := make([]Index, len(dIndexes))
for i, index := range dIndexes {
indexes[i] = Index(index)
}
return indexes, err
}
// nolint:staticcheck
if finder, ok := db.driverDB.(driver.Finder); ok {
dIndexes, err := finder.GetIndexes(ctx)
indexes := make([]Index, len(dIndexes))
for i, index := range dIndexes {
indexes[i] = Index(index)
}
return indexes, err
}
return nil, findNotImplemented
}
// QueryPlan is the query execution plan for a query, as returned by the Explain
// function.
type QueryPlan struct {
DBName string `json:"dbname"`
Index map[string]interface{} `json:"index"`
Selector map[string]interface{} `json:"selector"`
Options map[string]interface{} `json:"opts"`
Limit int64 `json:"limit"`
Skip int64 `json:"skip"`
// Fields is the list of fields to be returned in the result set, or
// an empty list if all fields are to be returned.
Fields []interface{} `json:"fields"`
Range map[string]interface{} `json:"range"`
}
// Explain returns the query plan for a given query. Explain takes the same
// arguments as Find.
func (db *DB) Explain(ctx context.Context, query interface{}, options ...Options) (*QueryPlan, error) {
if explainer, ok := db.driverDB.(driver.OptsFinder); ok {
plan, err := explainer.Explain(ctx, query, mergeOptions(options...))
if err != nil {
return nil, err
}
qp := QueryPlan(*plan)
return &qp, nil
}
// nolint:staticcheck
if explainer, ok := db.driverDB.(driver.Finder); ok {
plan, err := explainer.Explain(ctx, query)
if err != nil {
return nil, err
}
qp := QueryPlan(*plan)
return &qp, nil
}
return nil, findNotImplemented
}