Skip to content

#31: Skip NaN and infinity values #32

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Merged
merged 1 commit into from
Aug 26, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
## 1.1.0 [unreleased]

### Bugs
1. [#31](https://github.com/influxdata/influxdb-client-csharp/issues/31): Drop NaN and infinity values from fields when writing to InfluxDB

## 1.0.0 [2019-08-23]

### Features
Expand Down
57 changes: 34 additions & 23 deletions Client.Test/ItWriteQueryApiTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,11 @@ public async Task WriteRecordsList()
const string record2 = "h2o_feet,location=coyote_creek level\\ water_level=2.0 2";

_writeApi = Client.GetWriteApi();
var listener = new WriteApiTest.EventListener(_writeApi);
_writeApi.WriteRecords(bucketName, _organization.Id, WritePrecision.Ns,
new List<string> {record1, record2});
_writeApi.Flush();
listener.WaitToSuccess();

var query = await _queryApi.Query(
"from(bucket:\"" + bucketName + "\") |> range(start: 1970-01-01T00:00:00.000000001Z)",
Expand All @@ -91,7 +93,7 @@ public async Task WriteRecordsList()
Assert.AreEqual(2, records[1].GetValue());
Assert.AreEqual("level water_level", records[1].GetField());
}

[Test]
public async Task WriteAndQueryByOrganizationName()
{
Expand Down Expand Up @@ -206,7 +208,7 @@ public async Task WritePoints()

[Test]
public async Task WritePointsWithoutFields()
{
{
var bucketName = _bucket.Name;

var time = DateTime.UtcNow;
Expand Down Expand Up @@ -249,10 +251,11 @@ public async Task WritePointsWithoutFields()
public async Task WriteMeasurements()
{
_writeApi = Client.GetWriteApi();
var listener = new WriteApiTest.EventListener(_writeApi);

var bucketName = _bucket.Name;

var time = DateTime.UtcNow;
var time = DateTime.UtcNow.Add(-TimeSpan.FromSeconds(10));

var measurement1 = new H20Measurement
{
Expand All @@ -265,6 +268,7 @@ public async Task WriteMeasurements()

_writeApi.WriteMeasurements(bucketName, _organization.Id, WritePrecision.S, measurement1, measurement2);
_writeApi.Flush();
listener.WaitToSuccess();

var measurements = await _queryApi.Query<H20Measurement>(
"from(bucket:\"" + bucketName +
Expand All @@ -287,6 +291,7 @@ public async Task WriteMeasurements()
public async Task WriteMeasurementsWithoutFields()
{
_writeApi = Client.GetWriteApi();
var listener = new WriteApiTest.EventListener(_writeApi);

var bucketName = _bucket.Name;

Expand All @@ -303,6 +308,7 @@ public async Task WriteMeasurementsWithoutFields()

_writeApi.WriteMeasurements(bucketName, _organization.Id, WritePrecision.S, measurement1, measurement2);
_writeApi.Flush();
listener.WaitToSuccess();

var measurements = await _queryApi.Query<H20Measurement>(
"from(bucket:\"" + bucketName +
Expand All @@ -325,11 +331,13 @@ public async Task Flush()
var writeOptions = WriteOptions.CreateNew().BatchSize(10).FlushInterval(100_000).Build();

_writeApi = Client.GetWriteApi(writeOptions);
var listener = new WriteApiTest.EventListener(_writeApi);

var record = "h2o_feet,location=coyote_creek level\\ water_level=1.0 1";

_writeApi.WriteRecord(bucketName, _organization.Id, WritePrecision.Ns, record);
_writeApi.Flush();
listener.WaitToSuccess();

var query = await _queryApi.Query(
"from(bucket:\"" + bucketName + "\") |> range(start: 1970-01-01T00:00:00.000000001Z) |> last()",
Expand Down Expand Up @@ -647,10 +655,10 @@ public async Task WriteQueryWithDefaultOrgBucket()
public async Task DefaultTagsPoint()
{
Client.Dispose();

Environment.SetEnvironmentVariable("point-datacenter", "LA");
ConfigurationManager.AppSettings["point-sensor.version"] = "1.23a";

var options = new InfluxDBClientOptions.Builder().Url(InfluxDbUrl)
.AuthenticateToken(_token.ToCharArray())
.AddDefaultTag("id", "132-987-655")
Expand All @@ -660,9 +668,9 @@ public async Task DefaultTagsPoint()
.Build();

Client = InfluxDBClientFactory.Create(options);

var point = Point.Measurement("h2o_feet").Tag("location", "west").Field("water_level", 1);

_writeApi = Client.GetWriteApi();
var listener = new WriteApiTest.EventListener(_writeApi);
_writeApi.WritePoint(_bucket.Name, _organization.Id, point);
Expand All @@ -672,9 +680,10 @@ public async Task DefaultTagsPoint()

_queryApi = Client.GetQueryApi();
var tables = await _queryApi.Query(
"from(bucket:\"" + _bucket.Name + "\") |> range(start: 1970-01-01T00:00:00.000000001Z) |> pivot(rowKey:[\"_time\"], columnKey: [\"_field\"], valueColumn: \"_value\")",
"from(bucket:\"" + _bucket.Name +
"\") |> range(start: 1970-01-01T00:00:00.000000001Z) |> pivot(rowKey:[\"_time\"], columnKey: [\"_field\"], valueColumn: \"_value\")",
_organization.Id);

Assert.AreEqual(1, tables.Count);
Assert.AreEqual(1, tables[0].Records.Count);
Assert.AreEqual("h2o_feet", tables[0].Records[0].GetMeasurement());
Expand All @@ -690,10 +699,10 @@ public async Task DefaultTagsPoint()
public async Task DefaultTagsMeasurement()
{
Client.Dispose();

Environment.SetEnvironmentVariable("measurement-datacenter", "LA");
ConfigurationManager.AppSettings["measurement-sensor.version"] = "1.23a";

var options = new InfluxDBClientOptions.Builder().Url(InfluxDbUrl)
.AuthenticateToken(_token.ToCharArray())
.AddDefaultTag("id", "132-987-655")
Expand All @@ -703,12 +712,12 @@ public async Task DefaultTagsMeasurement()
.Build();

Client = InfluxDBClientFactory.Create(options);

var measurement1 = new H20Measurement
{
Location = "coyote_creek", Level = 2.927, Time = DateTime.UtcNow
};

_writeApi = Client.GetWriteApi();
var listener = new WriteApiTest.EventListener(_writeApi);
_writeApi.WriteMeasurement(_bucket.Name, _organization.Id, WritePrecision.Ms, measurement1);
Expand All @@ -718,9 +727,10 @@ public async Task DefaultTagsMeasurement()

_queryApi = Client.GetQueryApi();
var tables = await _queryApi.Query(
"from(bucket:\"" + _bucket.Name + "\") |> range(start: 1970-01-01T00:00:00.000000001Z) |> pivot(rowKey:[\"_time\"], columnKey: [\"_field\"], valueColumn: \"_value\")",
"from(bucket:\"" + _bucket.Name +
"\") |> range(start: 1970-01-01T00:00:00.000000001Z) |> pivot(rowKey:[\"_time\"], columnKey: [\"_field\"], valueColumn: \"_value\")",
_organization.Id);

Assert.AreEqual(1, tables.Count);
Assert.AreEqual(1, tables[0].Records.Count);
Assert.AreEqual("h2o", tables[0].Records[0].GetMeasurement());
Expand All @@ -731,7 +741,7 @@ public async Task DefaultTagsMeasurement()
Assert.AreEqual("1.23a", tables[0].Records[0].GetValueByKey("sensor-version"));
Assert.AreEqual("LA", tables[0].Records[0].GetValueByKey("env-var"));
}

[Test]
public async Task DefaultTagsConfiguration()
{
Expand All @@ -741,14 +751,14 @@ public async Task DefaultTagsConfiguration()
.LoadConfig()
.AuthenticateToken(_token.ToCharArray())
.Build();

Client = InfluxDBClientFactory.Create(options);

var measurement1 = new H20Measurement
{
Location = "coyote_creek", Level = 2.927, Time = DateTime.UtcNow
};

_writeApi = Client.GetWriteApi();
var listener = new WriteApiTest.EventListener(_writeApi);
_writeApi.WriteMeasurement(_bucket.Name, _organization.Id, WritePrecision.Ms, measurement1);
Expand All @@ -758,9 +768,10 @@ public async Task DefaultTagsConfiguration()

_queryApi = Client.GetQueryApi();
var tables = await _queryApi.Query(
"from(bucket:\"" + _bucket.Name + "\") |> range(start: 1970-01-01T00:00:00.000000001Z) |> pivot(rowKey:[\"_time\"], columnKey: [\"_field\"], valueColumn: \"_value\")",
"from(bucket:\"" + _bucket.Name +
"\") |> range(start: 1970-01-01T00:00:00.000000001Z) |> pivot(rowKey:[\"_time\"], columnKey: [\"_field\"], valueColumn: \"_value\")",
_organization.Id);

Assert.AreEqual(1, tables.Count);
Assert.AreEqual(1, tables[0].Records.Count);
Assert.AreEqual("h2o", tables[0].Records[0].GetMeasurement());
Expand All @@ -770,12 +781,12 @@ public async Task DefaultTagsConfiguration()
Assert.AreEqual("California Miner", tables[0].Records[0].GetValueByKey("customer"));
Assert.AreEqual("v1.00", tables[0].Records[0].GetValueByKey("version"));
}

[Test]
public async Task EnabledGzip()
{
Client.EnableGzip();

var bucketName = _bucket.Name;

const string record1 = "h2o_feet,location=coyote_creek level\\ water_level=1.0 1";
Expand Down
31 changes: 31 additions & 0 deletions Client.Test/PointTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -325,5 +325,36 @@ public void HasFields()
Assert.IsTrue(Point.Measurement("h2o").Field("level", "2").HasFields());
Assert.IsTrue(Point.Measurement("h2o").Tag("location", "europe").Field("level", "2").HasFields());
}

[Test]
public void InfinityValues()
{
var point = Point.Measurement("h2o")
.Tag("location", "europe")
.Field("double-infinity-positive", double.PositiveInfinity)
.Field("double-infinity-negative", double.NegativeInfinity)
.Field("double-nan", double.NaN)
.Field("flout-infinity-positive", float.PositiveInfinity)
.Field("flout-infinity-negative", float.NegativeInfinity)
.Field("flout-nan", float.NaN)
.Field("level", 2);

Assert.AreEqual("h2o,location=europe level=2i", point.ToLineProtocol());
}

[Test]
public void OnlyInfinityValues()
{
var point = Point.Measurement("h2o")
.Tag("location", "europe")
.Field("double-infinity-positive", double.PositiveInfinity)
.Field("double-infinity-negative", double.NegativeInfinity)
.Field("double-nan", double.NaN)
.Field("flout-infinity-positive", float.PositiveInfinity)
.Field("flout-infinity-negative", float.NegativeInfinity)
.Field("flout-nan", float.NaN);

Assert.AreEqual("", point.ToLineProtocol());
}
}
}
35 changes: 25 additions & 10 deletions Client/Writes/Point.cs
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ public bool HasFields()
{
return _fields.Count > 0;
}

/// <summary>
/// The Line Protocol
/// </summary>
Expand All @@ -256,7 +256,12 @@ public string ToLineProtocol(PointSettings pointSettings = null)

EscapeKey(sb, _measurementName);
AppendTags(sb, pointSettings);
AppendFields(sb);
var appendedFields = AppendFields(sb);
if (!appendedFields)
{
return "";
}

AppendTime(sb);

return sb.ToString();
Expand Down Expand Up @@ -312,16 +317,16 @@ private void AppendTags(StringBuilder writer, PointSettings pointSettings)
writer.Append(' ');
}

private void AppendFields(StringBuilder sb)
private bool AppendFields(StringBuilder sb)
{
var removeLast = false;
var appended = false;

foreach (var keyValue in _fields)
{
var key = keyValue.Key;
var value = keyValue.Value;

if (value == null)
if (IsNotDefined(value))
{
continue;
}
Expand Down Expand Up @@ -359,13 +364,15 @@ private void AppendFields(StringBuilder sb)
}

sb.Append(',');
removeLast = true;
appended = true;
}

if (removeLast)
if (appended)
{
sb.Remove(sb.Length - 1, 1);
}

return appended;
}

private void AppendTime(StringBuilder sb)
Expand Down Expand Up @@ -411,13 +418,21 @@ private void EscapeValue(StringBuilder sb, string value)
sb.Append(c);
}
}

private bool IsNotDefined(object value)
{
return value == null
|| (value is double d && (double.IsInfinity(d) || double.IsNaN(d)))
|| (value is float f && (float.IsInfinity(f) || float.IsNaN(f)));
}
}

internal static class DictionaryExtensions
{
public static SortedDictionary<K, V> ToSortedDictionary<K, V>(this Dictionary<K, V> existing, IComparer<K> comparer)
public static SortedDictionary<TK, TV> ToSortedDictionary<TK, TV>(this Dictionary<TK, TV> existing,
IComparer<TK> comparer)
{
return new SortedDictionary<K, V>(existing, comparer);
return new SortedDictionary<TK, TV>(existing, comparer);
}
}
}