diff --git a/CHANGELOG.md b/CHANGELOG.md index 1618320d2..494740dab 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,8 @@ ## 4.6.0 [unreleased] +### Bug Fixes +1. [#353](https://github.com/influxdata/influxdb-client-csharp/pull/353): Support for `double` types in LINQ expression [LINQ] + ## 4.5.0 [2022-08-29] ### Bug Fixes diff --git a/Client.Core.Test/AbstractTest.cs b/Client.Core.Test/AbstractTest.cs index ecb9c92a8..d37163755 100644 --- a/Client.Core.Test/AbstractTest.cs +++ b/Client.Core.Test/AbstractTest.cs @@ -1,5 +1,6 @@ using System; using System.Diagnostics; +using System.Globalization; using System.Net.Http; using System.Text; using System.Threading; @@ -124,5 +125,13 @@ private async Task InfluxDbRequest(HttpRequestMessage request) Assert.Fail("Unexpected exception: " + e); } } + + public static string GenerateName(string prefix) + { + Assert.IsNotEmpty(prefix); + + return prefix + DateTime.UtcNow.ToString("yyyy-MM-dd HH:mm:ss.ffffff", + CultureInfo.InvariantCulture) + "-IT"; + } } } \ No newline at end of file diff --git a/Client.Linq.Test/DomainObjects.cs b/Client.Linq.Test/DomainObjects.cs index 6b2dc57c0..73798a8b0 100644 --- a/Client.Linq.Test/DomainObjects.cs +++ b/Client.Linq.Test/DomainObjects.cs @@ -4,6 +4,22 @@ namespace Client.Linq.Test { + [Measurement("test_point")] + internal class InfluxPoint + { + [Column("int_value")] public int IntValue { get; set; } + + [Column("short_value")] public short ShortValue { get; set; } + + [Column("long_value")] public long LongValue { get; set; } + + [Column("double_value")] public double DoubleValue { get; set; } + + [Column("float_value")] public float FloatValue { get; set; } + + [Column("_time", IsTimestamp = true)] public DateTime Timestamp { get; set; } + } + [Measurement("sensor")] internal class Sensor { diff --git a/Client.Linq.Test/InfluxDBQueryVariableTest.cs b/Client.Linq.Test/InfluxDBQueryVariableTest.cs new file mode 100644 index 000000000..a11ce86fe --- /dev/null +++ b/Client.Linq.Test/InfluxDBQueryVariableTest.cs @@ -0,0 +1,186 @@ +using System; +using System.Linq; +using System.Threading.Tasks; +using InfluxDB.Client; +using InfluxDB.Client.Api.Domain; +using InfluxDB.Client.Core; +using InfluxDB.Client.Core.Test; +using InfluxDB.Client.Linq; +using NUnit.Framework; + +namespace Client.Linq.Test +{ + [TestFixture] + public class InfluxDbQueryVariableTest : AbstractTest + { + private InfluxDBClient _client; + private DateTime _dateTime; + private Bucket _bucket; + + [SetUp] + public new Task SetUp() + { + _client = InfluxDBClientFactory.Create(GetInfluxDb2Url(), "my-token"); + _client.SetLogLevel(LogLevel.Body); + return Task.CompletedTask; + } + + [OneTimeSetUp] + public async Task OneTimeSetUp() + { + _client = InfluxDBClientFactory.Create(GetInfluxDb2Url(), "my-token"); + _client.SetLogLevel(LogLevel.Body); + + _dateTime = DateTime.UtcNow; + + var orgId = (await _client.GetOrganizationsApi().FindOrganizationsAsync(org: "my-org")).First().Id; + _bucket = await _client.GetBucketsApi().CreateBucketAsync(GenerateName("test-bucket"), orgId); + + var point1 = new InfluxPoint() + { + IntValue = -1000, ShortValue = -1000, + LongValue = -1000, DoubleValue = -1000, FloatValue = -1000, Timestamp = _dateTime + }; + var point2 = new InfluxPoint() + { + IntValue = -450, ShortValue = -450, LongValue = -450, + DoubleValue = -450, FloatValue = -450, Timestamp = _dateTime.AddSeconds(-1) + }; + var point3 = new InfluxPoint() + { + IntValue = -80, ShortValue = -80, LongValue = -80, + DoubleValue = -80, FloatValue = -80, Timestamp = _dateTime.AddSeconds(-2) + }; + var point4 = new InfluxPoint() + { + IntValue = 65, ShortValue = 65, LongValue = 65, + DoubleValue = 65, FloatValue = 65, Timestamp = _dateTime.AddSeconds(-3) + }; + var point5 = new InfluxPoint() + { + IntValue = 190, ShortValue = 190, LongValue = 190, + DoubleValue = 190, FloatValue = 190, Timestamp = _dateTime.AddSeconds(-4) + }; + var point6 = new InfluxPoint() + { + IntValue = 350, ShortValue = 350, LongValue = 350, + DoubleValue = 350, FloatValue = 350, Timestamp = _dateTime.AddSeconds(-5) + }; + var point7 = new InfluxPoint() + { + IntValue = 500, ShortValue = 500, LongValue = 500, + DoubleValue = 500, FloatValue = 500, Timestamp = _dateTime.AddSeconds(-6) + }; + var point8 = new InfluxPoint() + { + IntValue = 750, ShortValue = 750, LongValue = 750, + DoubleValue = 750, FloatValue = 750, Timestamp = _dateTime.AddSeconds(-7) + }; + var point9 = new InfluxPoint() + { + IntValue = 1100, ShortValue = 1100, LongValue = 1100, + DoubleValue = 1100, FloatValue = 1100, Timestamp = _dateTime.AddSeconds(-8) + }; + var point10 = new InfluxPoint() + { + IntValue = 2535, ShortValue = 2535, LongValue = 2535, + DoubleValue = 2535, FloatValue = 2535, Timestamp = _dateTime.AddSeconds(-9) + }; + + await _client + .GetWriteApiAsync().WriteMeasurementsAsync(new[] + { + point1, point2, point3, point4, point5, point6, + point7, point8, point9, point10 + }, WritePrecision.Ns, _bucket.Name, "my-org"); + } + + [Test] + public void QueryAll() + { + var query = from s in InfluxDBQueryable + .Queryable(_bucket.Name, "my-org", _client.GetQueryApiSync()) + select s; + + var sensors = query.ToList(); + + Assert.AreEqual(10, sensors.Count); + } + + [Test] + public void QueryWhereInt() + { + var query = from s in InfluxDBQueryable + .Queryable(_bucket.Name, "my-org", _client.GetQueryApiSync()) + where s.IntValue > -200 + select s; + + var points = query.ToList(); + + Assert.AreEqual(8, points.Count); + foreach (var point in points) Assert.Greater(point.IntValue, -200); + } + + [Test] + public void QueryWhereShort() + { + var query = from s in InfluxDBQueryable + .Queryable(_bucket.Name, "my-org", _client.GetQueryApiSync()) + where s.ShortValue >= 500 + select s; + + var points = query.ToList(); + + Assert.AreEqual(4, points.Count); + foreach (var point in points) Assert.GreaterOrEqual(point.ShortValue, 500); + } + + [Test] + public void QueryWhereLong() + { + var query = from s in InfluxDBQueryable + .Queryable(_bucket.Name, "my-org", _client.GetQueryApiSync()) + where s.LongValue < 200 + select s; + + var points = query.ToList(); + + Assert.AreEqual(5, points.Count); + foreach (var point in points) Assert.Less(point.LongValue, 200); + } + + [Test] + public void QueryWhereDouble() + { + var query = from s in InfluxDBQueryable + .Queryable(_bucket.Name, "my-org", _client.GetQueryApiSync()) + where s.DoubleValue <= 0 + select s; + + var points = query.ToList(); + + Assert.AreEqual(3, points.Count); + foreach (var point in points) Assert.LessOrEqual(point.DoubleValue, 0); + } + + [Test] + public void QueryWhereFloat() + { + var query = from s in InfluxDBQueryable + .Queryable(_bucket.Name, "my-org", _client.GetQueryApiSync()) + where s.FloatValue < 100 + select s; + + var points = query.ToList(); + + Assert.AreEqual(4, points.Count); + foreach (var point in points) Assert.Less(point.FloatValue, 100); + } + + [TearDown] + protected void After() + { + _client.Dispose(); + } + } +} \ No newline at end of file diff --git a/Client.Linq/Internal/VariableAggregator.cs b/Client.Linq/Internal/VariableAggregator.cs index a5fc4e4c1..e09bb6b05 100644 --- a/Client.Linq/Internal/VariableAggregator.cs +++ b/Client.Linq/Internal/VariableAggregator.cs @@ -61,6 +61,8 @@ private Expression CreateExpression(NamedVariable variable) return new IntegerLiteral("IntegerLiteral", Convert.ToString(l)); case bool b: return new BooleanLiteral("BooleanLiteral", b); + case double d: + return new FloatLiteral("FloatLiteral", Convert.ToDecimal(d)); case float f: return new FloatLiteral("FloatLiteral", Convert.ToDecimal(f)); case DateTime d: diff --git a/Client.Test/AbstractItClientTest.cs b/Client.Test/AbstractItClientTest.cs index a81fe090d..75b5dcffa 100644 --- a/Client.Test/AbstractItClientTest.cs +++ b/Client.Test/AbstractItClientTest.cs @@ -1,5 +1,3 @@ -using System; -using System.Globalization; using System.Linq; using System.Threading.Tasks; using InfluxDB.Client.Api.Domain; @@ -34,14 +32,6 @@ protected void After() Client.Dispose(); } - public static string GenerateName(string prefix) - { - Assert.IsNotEmpty(prefix); - - return prefix + DateTime.UtcNow.ToString("yyyy-MM-dd HH:mm:ss.ffffff", - CultureInfo.InvariantCulture) + "-IT"; - } - protected async Task FindMyOrg() { var org = (await Client.GetOrganizationsApi().FindOrganizationsAsync(100)) diff --git a/Client.Test/ItMonitoringAlertingTest.cs b/Client.Test/ItMonitoringAlertingTest.cs index c6a0efe39..43cfca52d 100644 --- a/Client.Test/ItMonitoringAlertingTest.cs +++ b/Client.Test/ItMonitoringAlertingTest.cs @@ -79,7 +79,7 @@ public async Task CreateMonitoringAndAlerting() var message = "The Stock price for XYZ is on: ${ r._level } level!"; - await checksApi.CreateThresholdCheckAsync(AbstractItClientTest.GenerateName("XYZ Stock value"), query, "5s", + await checksApi.CreateThresholdCheckAsync(GenerateName("XYZ Stock value"), query, "5s", message, threshold, org.Id); @@ -89,7 +89,7 @@ await checksApi.CreateThresholdCheckAsync(AbstractItClientTest.GenerateName("XYZ var url = MockServerUrl; var endpoint = await notificationEndpointsApi.CreateSlackEndpointAsync( - AbstractItClientTest.GenerateName("Slack Endpoint"), url, org.Id); + GenerateName("Slack Endpoint"), url, org.Id); // // Create Notification Rule @@ -97,7 +97,7 @@ await notificationEndpointsApi.CreateSlackEndpointAsync( // Send message if the status is 'Critical' // await notificationRulesApi.CreateSlackRuleAsync( - AbstractItClientTest.GenerateName("Critical status to Slack"), "10s", "${ r._message }", + GenerateName("Critical status to Slack"), "10s", "${ r._message }", RuleStatusLevel.CRIT, endpoint, org.Id);