/
result.go
141 lines (123 loc) · 4.02 KB
/
result.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
129
130
131
132
133
134
135
136
137
138
139
140
141
package query
import (
"encoding/json"
"errors"
"fmt"
"github.com/influxdata/influxdb/models"
"github.com/influxdata/influxql"
)
const (
// WarningLevel is the message level for a warning.
WarningLevel = "warning"
)
// TagSet is a fundamental concept within the query system. It represents a composite series,
// composed of multiple individual series that share a set of tag attributes.
type TagSet struct {
Tags map[string]string
Filters []influxql.Expr
SeriesKeys []string
Key []byte
}
// AddFilter adds a series-level filter to the Tagset.
func (t *TagSet) AddFilter(key string, filter influxql.Expr) {
t.SeriesKeys = append(t.SeriesKeys, key)
t.Filters = append(t.Filters, filter)
}
func (t *TagSet) Len() int { return len(t.SeriesKeys) }
func (t *TagSet) Less(i, j int) bool { return t.SeriesKeys[i] < t.SeriesKeys[j] }
func (t *TagSet) Swap(i, j int) {
t.SeriesKeys[i], t.SeriesKeys[j] = t.SeriesKeys[j], t.SeriesKeys[i]
t.Filters[i], t.Filters[j] = t.Filters[j], t.Filters[i]
}
// Reverse reverses the order of series keys and filters in the TagSet.
func (t *TagSet) Reverse() {
for i, j := 0, len(t.Filters)-1; i < j; i, j = i+1, j-1 {
t.Filters[i], t.Filters[j] = t.Filters[j], t.Filters[i]
t.SeriesKeys[i], t.SeriesKeys[j] = t.SeriesKeys[j], t.SeriesKeys[i]
}
}
// LimitTagSets returns a tag set list with SLIMIT and SOFFSET applied.
func LimitTagSets(a []*TagSet, slimit, soffset int) []*TagSet {
// Ignore if no limit or offset is specified.
if slimit == 0 && soffset == 0 {
return a
}
// If offset is beyond the number of tag sets then return nil.
if soffset > len(a) {
return nil
}
// Clamp limit to the max number of tag sets.
if soffset+slimit > len(a) {
slimit = len(a) - soffset
}
return a[soffset : soffset+slimit]
}
// Message represents a user-facing message to be included with the result.
type Message struct {
Level string `json:"level"`
Text string `json:"text"`
}
// ReadOnlyWarning generates a warning message that tells the user the command
// they are using is being used for writing in a read only context.
//
// This is a temporary method while to be used while transitioning to read only
// operations for issue #6290.
func ReadOnlyWarning(stmt string) *Message {
return &Message{
Level: WarningLevel,
Text: fmt.Sprintf("deprecated use of '%s' in a read only context, please use a POST request instead", stmt),
}
}
// Result represents a resultset returned from a single statement.
// Rows represents a list of rows that can be sorted consistently by name/tag.
type Result struct {
// StatementID is just the statement's position in the query. It's used
// to combine statement results if they're being buffered in memory.
StatementID int
Series models.Rows
Messages []*Message
Partial bool
Err error
}
// MarshalJSON encodes the result into JSON.
func (r *Result) MarshalJSON() ([]byte, error) {
// Define a struct that outputs "error" as a string.
var o struct {
StatementID int `json:"statement_id"`
Series []*models.Row `json:"series,omitempty"`
Messages []*Message `json:"messages,omitempty"`
Partial bool `json:"partial,omitempty"`
Err string `json:"error,omitempty"`
}
// Copy fields to output struct.
o.StatementID = r.StatementID
o.Series = r.Series
o.Messages = r.Messages
o.Partial = r.Partial
if r.Err != nil {
o.Err = r.Err.Error()
}
return json.Marshal(&o)
}
// UnmarshalJSON decodes the data into the Result struct
func (r *Result) UnmarshalJSON(b []byte) error {
var o struct {
StatementID int `json:"statement_id"`
Series []*models.Row `json:"series,omitempty"`
Messages []*Message `json:"messages,omitempty"`
Partial bool `json:"partial,omitempty"`
Err string `json:"error,omitempty"`
}
err := json.Unmarshal(b, &o)
if err != nil {
return err
}
r.StatementID = o.StatementID
r.Series = o.Series
r.Messages = o.Messages
r.Partial = o.Partial
if o.Err != "" {
r.Err = errors.New(o.Err)
}
return nil
}