Add support for uint64 in the clients
parent
e0746762d9
commit
2f47c3d28f
|
@ -164,6 +164,14 @@ func writePoints(clnt client.Client) {
|
|||
}
|
||||
```
|
||||
|
||||
#### Uint64 Support
|
||||
|
||||
The `uint64` data type is supported if your server is version `1.4.0` or
|
||||
greater. To write a data point as an unsigned integer, you must insert
|
||||
the point as `uint64`. You cannot use `uint` or any of the other
|
||||
derivatives because previous versions of the client have supported
|
||||
writing those types as an integer.
|
||||
|
||||
### Querying Data
|
||||
|
||||
One nice advantage of using **InfluxDB** the ability to query your data using familiar
|
||||
|
|
|
@ -785,7 +785,7 @@ func (c *Client) Addr() string {
|
|||
func checkPointTypes(p Point) error {
|
||||
for _, v := range p.Fields {
|
||||
switch v.(type) {
|
||||
case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, float32, float64, bool, string, nil:
|
||||
case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, float32, float64, bool, string, nil:
|
||||
return nil
|
||||
default:
|
||||
return fmt.Errorf("unsupported point type: %T", v)
|
||||
|
|
|
@ -307,6 +307,12 @@ func TestClient_BasicAuth(t *testing.T) {
|
|||
|
||||
func TestClient_Write(t *testing.T) {
|
||||
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
in, err := ioutil.ReadAll(r.Body)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %s", err)
|
||||
} else if have, want := strings.TrimSpace(string(in)), `m0,host=server01 v1=2,v2=2i,v3=2u,v4="foobar",v5=true 0`; have != want {
|
||||
t.Errorf("unexpected write protocol: %s != %s", have, want)
|
||||
}
|
||||
var data client.Response
|
||||
w.WriteHeader(http.StatusNoContent)
|
||||
_ = json.NewEncoder(w).Encode(data)
|
||||
|
@ -320,7 +326,24 @@ func TestClient_Write(t *testing.T) {
|
|||
t.Fatalf("unexpected error. expected %v, actual %v", nil, err)
|
||||
}
|
||||
|
||||
bp := client.BatchPoints{}
|
||||
bp := client.BatchPoints{
|
||||
Points: []client.Point{
|
||||
{
|
||||
Measurement: "m0",
|
||||
Tags: map[string]string{
|
||||
"host": "server01",
|
||||
},
|
||||
Time: time.Unix(0, 0).UTC(),
|
||||
Fields: map[string]interface{}{
|
||||
"v1": float64(2),
|
||||
"v2": int64(2),
|
||||
"v3": uint64(2),
|
||||
"v4": "foobar",
|
||||
"v5": true,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
r, err := c.Write(bp)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error. expected %v, actual %v", nil, err)
|
||||
|
@ -724,36 +747,6 @@ func TestClient_NoTimeout(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestClient_WriteUint64(t *testing.T) {
|
||||
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
var data client.Response
|
||||
w.WriteHeader(http.StatusNoContent)
|
||||
_ = json.NewEncoder(w).Encode(data)
|
||||
}))
|
||||
defer ts.Close()
|
||||
|
||||
u, _ := url.Parse(ts.URL)
|
||||
config := client.Config{URL: *u}
|
||||
c, err := client.NewClient(config)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error. expected %v, actual %v", nil, err)
|
||||
}
|
||||
bp := client.BatchPoints{
|
||||
Points: []client.Point{
|
||||
{
|
||||
Fields: map[string]interface{}{"value": uint64(10)},
|
||||
},
|
||||
},
|
||||
}
|
||||
r, err := c.Write(bp)
|
||||
if err == nil {
|
||||
t.Fatalf("unexpected error. expected err, actual %v", err)
|
||||
}
|
||||
if r != nil {
|
||||
t.Fatalf("unexpected response. expected %v, actual %v", nil, r)
|
||||
}
|
||||
}
|
||||
|
||||
func TestClient_ParseConnectionString_IPv6(t *testing.T) {
|
||||
path := "[fdf5:9ede:1875:0:a9ee:a600:8fe3:d495]:8086"
|
||||
u, err := client.ParseConnectionString(path, false)
|
||||
|
|
|
@ -3,6 +3,7 @@ package client
|
|||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"reflect"
|
||||
|
@ -330,6 +331,12 @@ func TestClient_Concurrent_Use(t *testing.T) {
|
|||
|
||||
func TestClient_Write(t *testing.T) {
|
||||
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
in, err := ioutil.ReadAll(r.Body)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %s", err)
|
||||
} else if have, want := strings.TrimSpace(string(in)), `m0,host=server01 v1=2,v2=2i,v3=2u,v4="foobar",v5=true 0`; have != want {
|
||||
t.Errorf("unexpected write protocol: %s != %s", have, want)
|
||||
}
|
||||
var data Response
|
||||
w.WriteHeader(http.StatusNoContent)
|
||||
_ = json.NewEncoder(w).Encode(data)
|
||||
|
@ -344,6 +351,24 @@ func TestClient_Write(t *testing.T) {
|
|||
if err != nil {
|
||||
t.Errorf("unexpected error. expected %v, actual %v", nil, err)
|
||||
}
|
||||
pt, err := NewPoint(
|
||||
"m0",
|
||||
map[string]string{
|
||||
"host": "server01",
|
||||
},
|
||||
map[string]interface{}{
|
||||
"v1": float64(2),
|
||||
"v2": int64(2),
|
||||
"v3": uint64(2),
|
||||
"v4": "foobar",
|
||||
"v5": true,
|
||||
},
|
||||
time.Unix(0, 0).UTC(),
|
||||
)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error. expected %v, actual %v", nil, err)
|
||||
}
|
||||
bp.AddPoint(pt)
|
||||
err = c.Write(bp)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error. expected %v, actual %v", nil, err)
|
||||
|
|
|
@ -2248,6 +2248,9 @@ func appendField(b []byte, k string, v interface{}) []byte {
|
|||
case int:
|
||||
b = strconv.AppendInt(b, int64(v), 10)
|
||||
b = append(b, 'i')
|
||||
case uint64:
|
||||
b = strconv.AppendUint(b, v, 10)
|
||||
b = append(b, 'u')
|
||||
case uint32:
|
||||
b = strconv.AppendInt(b, int64(v), 10)
|
||||
b = append(b, 'i')
|
||||
|
@ -2257,10 +2260,9 @@ func appendField(b []byte, k string, v interface{}) []byte {
|
|||
case uint8:
|
||||
b = strconv.AppendInt(b, int64(v), 10)
|
||||
b = append(b, 'i')
|
||||
// TODO: 'uint' should be considered just as "dangerous" as a uint64,
|
||||
// perhaps the value should be checked and capped at MaxInt64? We could
|
||||
// then include uint64 as an accepted value
|
||||
case uint:
|
||||
// TODO: 'uint' should be converted to writing as an unsigned integer,
|
||||
// but we cannot since that would break backwards compatibility.
|
||||
b = strconv.AppendInt(b, int64(v), 10)
|
||||
b = append(b, 'i')
|
||||
case float32:
|
||||
|
|
|
@ -40,6 +40,47 @@ func TestMarshal(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestMarshalFields(t *testing.T) {
|
||||
for _, tt := range []struct {
|
||||
name string
|
||||
value interface{}
|
||||
exp string
|
||||
}{
|
||||
{
|
||||
name: "Float",
|
||||
value: float64(2),
|
||||
exp: `value=2`,
|
||||
},
|
||||
{
|
||||
name: "Integer",
|
||||
value: int64(2),
|
||||
exp: `value=2i`,
|
||||
},
|
||||
{
|
||||
name: "Unsigned",
|
||||
value: uint64(2),
|
||||
exp: `value=2u`,
|
||||
},
|
||||
{
|
||||
name: "String",
|
||||
value: "foobar",
|
||||
exp: `value="foobar"`,
|
||||
},
|
||||
{
|
||||
name: "Boolean",
|
||||
value: true,
|
||||
exp: `value=true`,
|
||||
},
|
||||
} {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
fields := map[string]interface{}{"value": tt.value}
|
||||
if have, want := models.Fields(fields).MarshalBinary(), []byte(tt.exp); !bytes.Equal(have, want) {
|
||||
t.Fatalf("unexpected field output: %s != %s", string(have), string(want))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestTags_HashKey(t *testing.T) {
|
||||
tags = models.NewTags(map[string]string{"A FOO": "bar", "APPLE": "orange", "host": "serverA", "region": "uswest"})
|
||||
got := tags.HashKey()
|
||||
|
|
Loading…
Reference in New Issue