forked from influxdata/influxdb-client-go
-
Notifications
You must be signed in to change notification settings - Fork 0
/
point.go
160 lines (142 loc) · 3.52 KB
/
point.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
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
// Copyright 2020 InfluxData, Inc. All rights reserved.
// Use of this source code is governed by MIT
// license that can be found in the LICENSE file.
package influxdb2
import (
"sort"
"time"
lp "github.com/influxdata/line-protocol"
)
// Point is represents InfluxDB time series point, holding tags and fields
type Point struct {
measurement string
tags []*lp.Tag
fields []*lp.Field
timestamp time.Time
}
// TagList returns a slice containing tags of a Point.
func (m *Point) TagList() []*lp.Tag {
return m.tags
}
// FieldList returns a slice containing the fields of a Point.
func (m *Point) FieldList() []*lp.Field {
return m.fields
}
// SetTime set timestamp for a Point.
func (m *Point) SetTime(timestamp time.Time) *Point {
m.timestamp = timestamp
return m
}
// Time is the timestamp of a Point.
func (m *Point) Time() time.Time {
return m.timestamp
}
// SortTags orders the tags of a point alphanumerically by key.
// This is just here as a helper, to make it easy to keep tags sorted if you are creating a Point manually.
func (m *Point) SortTags() *Point {
sort.Slice(m.tags, func(i, j int) bool { return m.tags[i].Key < m.tags[j].Key })
return m
}
// SortFields orders the fields of a point alphanumerically by key.
func (m *Point) SortFields() *Point {
sort.Slice(m.fields, func(i, j int) bool { return m.fields[i].Key < m.fields[j].Key })
return m
}
// AddTag adds a tag to a point.
func (m *Point) AddTag(k, v string) *Point {
for i, tag := range m.tags {
if k == tag.Key {
m.tags[i].Value = v
return m
}
}
m.tags = append(m.tags, &lp.Tag{Key: k, Value: v})
return m
}
// AddField adds a field to a point.
func (m *Point) AddField(k string, v interface{}) *Point {
for i, field := range m.fields {
if k == field.Key {
m.fields[i].Value = v
return m
}
}
m.fields = append(m.fields, &lp.Field{Key: k, Value: convertField(v)})
return m
}
// Name returns the name of measurement of a point.
func (m *Point) Name() string {
return m.measurement
}
// NewPointWithMeasurement creates a empty Point
// Use AddTag and AddField to fill point with data
func NewPointWithMeasurement(measurement string) *Point {
return &Point{measurement: measurement}
}
// NewPoint creates a Point from measurement name, tags, fields and a timestamp.
func NewPoint(
measurement string,
tags map[string]string,
fields map[string]interface{},
ts time.Time,
) *Point {
m := &Point{
measurement: measurement,
tags: nil,
fields: nil,
timestamp: ts,
}
if len(tags) > 0 {
m.tags = make([]*lp.Tag, 0, len(tags))
for k, v := range tags {
m.tags = append(m.tags,
&lp.Tag{Key: k, Value: v})
}
}
m.fields = make([]*lp.Field, 0, len(fields))
for k, v := range fields {
v := convertField(v)
if v == nil {
continue
}
m.fields = append(m.fields, &lp.Field{Key: k, Value: v})
}
m.SortFields()
m.SortTags()
return m
}
// convertField converts any primitive type to types supported by line protocol
func convertField(v interface{}) interface{} {
switch v := v.(type) {
case bool, int64, string, float64:
return v
case int:
return int64(v)
case uint:
return uint64(v)
case uint64:
return v
case []byte:
return string(v)
case int32:
return int64(v)
case int16:
return int64(v)
case int8:
return int64(v)
case uint32:
return uint64(v)
case uint16:
return uint64(v)
case uint8:
return uint64(v)
case float32:
return float64(v)
case time.Time:
return v.Format(time.RFC3339Nano)
case time.Duration:
return v.String()
default:
panic("unsupported type")
}
}