private static async Task <InfluxResultSet <TInfluxRow> > CreateBasedOnInterfaceAsync <TInfluxRow, TTimestamp>( InfluxClient client, IEnumerable <QueryResult> queryResults, string db, bool allowMetadataQuerying, InfluxRowTypeInfo <TInfluxRow> propertyMap, InfluxQueryOptions options, CancellationToken cancellationToken = default) where TInfluxRow : IInfluxRow <TTimestamp>, new() { var timestampParser = client.TimestampParserRegistry.FindTimestampParserOrNull <TTimestamp>(); // In this case, we will contruct objects based on the IInfluxRow interface Dictionary <int, InfluxResult <TInfluxRow> > results = new Dictionary <int, InfluxResult <TInfluxRow> >(); foreach (var queryResult in queryResults) { foreach (var result in queryResult.Results) { InfluxResult <TInfluxRow> existingResult; if (!results.TryGetValue(result.StatementId, out existingResult)) { existingResult = new InfluxResult <TInfluxRow>(result.StatementId, result.Error ?? (result.Series == null ? Errors.UnexpectedQueryResult : null)); results.Add(result.StatementId, existingResult); } else { existingResult.AppendErrorMessage(result.Error); } if (existingResult.Succeeded) { foreach (var series in result.Series) { var name = series.Name; // create influx series var tags = series.Tags?.ToDictionary(x => x.Key, x => x.Value == string.Empty ? null : (object)x.Value) ?? new Dictionary <string, object>(); // find or create influx serie var influxSerie = existingResult.FindGroupInternal(name, tags, true); if (influxSerie == null) { influxSerie = new InfluxSeries <TInfluxRow>(name, tags); existingResult.Series.Add(influxSerie); } // add data to found series await AddValuesToInfluxSeriesByInterfaceAsync <TInfluxRow, TTimestamp>( influxSerie, series, client, db, allowMetadataQuerying, propertyMap, options, timestampParser, cancellationToken); } } } } return(new InfluxResultSet <TInfluxRow>(results.Values.ToList())); }
private static InfluxResultSet <TInfluxRow> CreateBasedOnAttributes <TInfluxRow, TTimestamp>( InfluxClient client, IEnumerable <QueryResult> queryResults, InfluxQueryOptions options, InfluxRowTypeInfo <TInfluxRow> propertyMap) where TInfluxRow : new() { // Create type based on attributes Dictionary <int, InfluxResult <TInfluxRow> > results = new Dictionary <int, InfluxResult <TInfluxRow> >(); var timestampParser = client.TimestampParserRegistry.FindTimestampParserOrNull <TTimestamp>(); foreach (var queryResult in queryResults) { foreach (var result in queryResult.Results) { InfluxResult <TInfluxRow> existingResult; if (!results.TryGetValue(result.StatementId, out existingResult)) { existingResult = new InfluxResult <TInfluxRow>(result.StatementId, result.Error ?? (result.Series == null ? Errors.UnexpectedQueryResult : null)); results.Add(result.StatementId, existingResult); } else { existingResult.AppendErrorMessage(result.Error); } // TODO: What if error message is given in following query? if (existingResult.Succeeded) { foreach (var series in result.Series) { var name = series.Name; // create new dictionary, with correct typing (we must potentially convert strings to enums, if the column being used in the GROUP BY is an enum) var tags = CreateTagDictionaryFromSerieBasedOnAttributes(series, propertyMap.All); // find or create influx serie var influxSerie = existingResult.FindGroupInternal(name, tags, true); if (influxSerie == null) { influxSerie = new InfluxSeries <TInfluxRow>(name, tags); existingResult.Series.Add(influxSerie); } // add data to found serie AddValuesToInfluxSeriesByAttributes <TInfluxRow, TTimestamp>(influxSerie, series, propertyMap, options, timestampParser); } } } } return(new InfluxResultSet <TInfluxRow>(results.Values.ToList())); }
public async Task <List <MeasurementRow> > ReadAllMeasurements() { InfluxResult <MeasurementRow> resultSet = await _influxClient.ShowMeasurementsAsync(TimeSeriesSettings.InfluxDatabase); if (resultSet.Series.Count > 0) { InfluxSeries <MeasurementRow> result = resultSet.Series[0]; return(result.Rows); } else { return(new List <MeasurementRow>()); } }
private RoomData MapToRoomData(InfluxSeries <RoomData> serie) { RoomData roomData = serie.Rows[0]; roomData.Temperature = RoundValue(roomData.Temperature); roomData.MinTemperature = RoundValue(roomData.MinTemperature); roomData.MaxTemperature = RoundValue(roomData.MaxTemperature); roomData.Humidity = RoundValue(roomData.Humidity); roomData.RoomName = serie.GroupedTags["name"].ToString(); if (roomData.RoomName == "Aussen") { roomData.Type = RoomType.Outdoor; } return(roomData); }
private static async Task AddValuesToInfluxSeriesByInterfaceAsync <TInfluxRow, TTimestamp>( InfluxSeries <TInfluxRow> influxSerie, SeriesResult series, InfluxClient client, string db, bool allowMetadataQuerying, InfluxRowTypeInfo <TInfluxRow> propertyMap, InfluxQueryOptions options, ITimestampParser <TTimestamp> timestampParser) where TInfluxRow : IInfluxRow <TTimestamp>, new() { // Values will be null, if there are no entries in the result set if (series.Values != null) { var precision = options.Precision; var name = series.Name; var columns = series.Columns; var setters = new Action <TInfluxRow, string, object> [columns.Count]; var dataPoints = new List <TInfluxRow>(); // Get metadata information about the measurement we are querying, as we dont know // which columns are tags/fields otherwise DatabaseMeasurementInfo meta = null; if (allowMetadataQuerying) { meta = await client.GetMetaInformationAsync(db, name, options.MetadataExpiration).ConfigureAwait(false); } for (int i = 0; i < columns.Count; i++) { var columnName = columns[i]; if (!allowMetadataQuerying) { setters[i] = (row, fieldName, value) => row.SetField(fieldName, value); } else if (columnName == InfluxConstants.TimeColumn) { setters[i] = (row, timeName, value) => row.SetTimestamp(timestampParser.ToTimestamp(options.Precision, value)); } else if (meta.Tags.Contains(columnName)) { setters[i] = (row, tagName, value) => row.SetTag(tagName, (string)value); } else { setters[i] = (row, fieldName, value) => row.SetField(fieldName, value); } } // constructs the IInfluxRows using the IInfluxRow interface foreach (var values in series.Values) { var dataPoint = new TInfluxRow(); propertyMap.SetMeasurementName(name, dataPoint); // go through all values that are stored as a List<List<object>> for (int i = 0; i < values.Count; i++) { var value = values[i]; // TODO: What about NULL values? Are they treated as empty strings or actual nulls? if (value != null) { setters[i](dataPoint, columns[i], value); } } dataPoints.Add(dataPoint); } influxSerie.Rows.AddRange(dataPoints); } }
private static void AddValuesToInfluxSeriesByAttributes <TInfluxRow, TTimestamp>( InfluxSeries <TInfluxRow> influxSerie, SeriesResult series, InfluxRowTypeInfo <TInfluxRow> propertyMap, InfluxQueryOptions options, ITimestampParser <TTimestamp> timestampParser) where TInfluxRow : new() { // Values will be null, if there are no entries in the result set if (series.Values != null) { var dataPoints = new List <TInfluxRow>(); var precision = options.Precision; var columns = series.Columns; var name = series.Name; // construct an array of properties based on the same indexing as the columns returned by the query var properties = new PropertyExpressionInfo <TInfluxRow> [columns.Count]; for (int i = 0; i < columns.Count; i++) { PropertyExpressionInfo <TInfluxRow> propertyInfo; if (propertyMap.All.TryGetValue(columns[i], out propertyInfo)) { properties[i] = propertyInfo; } } foreach (var values in series.Values) { // construct the data points based on the attributes var dataPoint = new TInfluxRow(); propertyMap.SetMeasurementName(name, dataPoint); for (int i = 0; i < values.Count; i++) { var value = values[i]; // TODO: What about NULL values? Are they treated as empty strings or actual nulls? var property = properties[i]; // set the value based on the property, if both the value and property is not null if (property != null) { if (value != null) { if (property.Key == InfluxConstants.TimeColumn) { property.SetValue(dataPoint, timestampParser.ToTimestamp(options.Precision, value)); } else if (property.IsDateTime) { property.SetValue(dataPoint, DateTime.Parse((string)value, CultureInfo.InvariantCulture, OnlyUtcStyles)); } else if (property.IsEnum) { property.SetValue(dataPoint, property.GetEnumValue(value)); } else { // will throw exception if types does not match up property.SetValue(dataPoint, Convert.ChangeType(value, property.Type, CultureInfo.InvariantCulture)); } } } } dataPoints.Add(dataPoint); } influxSerie.Rows.AddRange(dataPoints); } }
public async Task <bool> ConsumeNextSerieAsync(CancellationToken cancellationToken = default) { if (_consumeCurrentSerieNextTime) { _consumeCurrentSerieNextTime = false; if (_currentStatementId != _currentResult.StatementId) { _consumeCurrentResultNextTime = true; _currentTags = null; _capturedSerie = null; return(false); } if (!InfluxSeriesComparer.Compare(_currentSerie.GroupedTags, _currentTags)) { _currentTags = _currentSerie.GroupedTags; _capturedSerie = _currentSerie; _currentBatch = _currentSerie.Rows; return(true); } } bool hasMoreSeries; bool hasMoreResultsForCurrentStatement = true; while (hasMoreResultsForCurrentStatement) // hasMoreResults { do { // might need to consume both results and series hasMoreSeries = await _resultIterator.ConsumeNextSerieAsync(cancellationToken).ConfigureAwait(false); if (hasMoreSeries) { // consume until the grouped tags changes _currentSerie = _resultIterator.CurrentSerie; if (!InfluxSeriesComparer.Compare(_currentSerie.GroupedTags, _currentTags)) { _currentTags = _currentSerie.GroupedTags; _currentBatch = _currentSerie.Rows; _capturedSerie = _currentSerie; return(true); } } } while(hasMoreSeries); // handle the next result to see if it contains more data for the current statement var hasMoreResults = await _resultIterator.ConsumeNextResultAsync(cancellationToken).ConfigureAwait(false); if (hasMoreResults) { _currentResult = _resultIterator.CurrentResult; hasMoreResultsForCurrentStatement = _currentResult.StatementId == _currentStatementId; if (!hasMoreResultsForCurrentStatement) { _consumeCurrentResultNextTime = true; } } else { hasMoreResultsForCurrentStatement = false; } } _capturedSerie = null; _currentTags = null; return(false); }