private static InfluxResultSet <TInfluxRow> CreateBasedOnAttributes <TInfluxRow>(QueryResult queryResult) where TInfluxRow : new() { // Create type based on attributes List <InfluxResult <TInfluxRow> > results = new List <InfluxResult <TInfluxRow> >(); var propertyMap = MetadataCache.GetOrCreate <TInfluxRow>().All; foreach (var result in queryResult.Results) { var influxSeries = new List <InfluxSeries <TInfluxRow> >(); if (result.Series != null && result.Error == null) { foreach (var series in result.Series) { var name = series.Name; var columns = series.Columns; var dataPoints = new List <TInfluxRow>(); // Values will be null, if there are no entries in the result set if (series.Values != null) { // 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.TryGetValue(columns[i], out propertyInfo)) { properties[i] = propertyInfo; } } foreach (var values in series.Values) { // construct the data points based on the attributes var row = new TInfluxRow(); // if we implement IHaveMeasurementName, set the measurement name on the IInfluxRow as well var seriesDataPoint = dataPoints as IHaveMeasurementName; if (seriesDataPoint != null) { seriesDataPoint.MeasurementName = name; } 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.IsDateTime) { property.SetValue(row, DateTime.Parse((string)value, CultureInfo.InvariantCulture, DateTimeStyles)); } else if (property.IsEnum) { property.SetValue(row, property.GetEnumValue(value)); } else { property.SetValue(row, Convert.ChangeType(value, property.Type, CultureInfo.InvariantCulture)); } } } } dataPoints.Add(row); } } // 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) Dictionary <string, object> tags = null; if (series.Tags != null) { tags = new Dictionary <string, object>(); foreach (var kvp in series.Tags) { object value; if (!string.IsNullOrEmpty(kvp.Value)) { PropertyExpressionInfo <TInfluxRow> property; if (propertyMap.TryGetValue(kvp.Key, out property)) { // we know this is either an enum or a string if (property.IsEnum) { Enum valueAsEnum; if (property.StringToEnum.TryGetValue(kvp.Value, out valueAsEnum)) { value = valueAsEnum; } else { // could not find the value, simply use the string representation value = kvp.Value; } } else { // since kvp.Value is just a string, so go for it value = kvp.Value; } } else { value = kvp.Value; } } else { value = null; } tags.Add(kvp.Key, value); } } influxSeries.Add(new InfluxSeries <TInfluxRow>(name, dataPoints, tags)); } } results.Add(new InfluxResult <TInfluxRow>(influxSeries, result.Error ?? (result.Series == null ? Errors.UnexpectedQueryResult : null))); } return(new InfluxResultSet <TInfluxRow>(results)); }
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); } }
protected override Task SerializeToStreamAsync(Stream stream, TransportContext context) { var writer = new StreamWriter(stream, UTF8); var precision = _precision; var getMeasurementName = _getMeasurementName; if (ResultSetFactory.IsIInfluxRow <TInfluxRow>()) { foreach (IInfluxRow dp in _dataPoints) { // write measurement name writer.Write(getMeasurementName((TInfluxRow)dp)); // write all tags foreach (var kvp in dp.GetAllTags()) // Ensure tags are in correct order? { var value = kvp.Value; if (value != null) { writer.Write(','); writer.Write(LineProtocolEscape.EscapeKey(kvp.Key)); writer.Write('='); writer.Write(LineProtocolEscape.EscapeTagValue(value)); } } // write tag to field seperator writer.Write(' '); // write all fields using (var enumerator = dp.GetAllFields().GetEnumerator()) { bool hasMore = enumerator.MoveNext(); bool hasValue = false; object value = null; KeyValuePair <string, object> current = default(KeyValuePair <string, object>); while (hasMore && !hasValue) { current = enumerator.Current; value = enumerator.Current.Value; hasValue = value != null; hasMore = enumerator.MoveNext(); } while (hasValue) { writer.Write(LineProtocolEscape.EscapeKey(current.Key)); writer.Write('='); writer.Write(LineProtocolEscape.EscapeFieldValue(value)); // get a hold of the next non-null value hasValue = false; while (hasMore && !hasValue) { current = enumerator.Current; value = enumerator.Current.Value; hasValue = value != null; hasMore = enumerator.MoveNext(); } // we have just written a value, and now we have the next non-null value if (hasValue) { writer.Write(','); } } } // write timestamp, if exists var ts = dp.GetTimestamp(); if (ts != null) { writer.Write(' '); long ticks = ts.Value.ToPrecision(precision); writer.Write(ticks); } writer.Write('\n'); } } else { var cache = MetadataCache.GetOrCreate <TInfluxRow>(); var tags = cache.Tags; var fields = cache.Fields; var timestamp = cache.Timestamp; foreach (var dp in _dataPoints) { // write measurement name writer.Write(getMeasurementName(dp)); // write all tags if (tags.Count > 0) { foreach (var tagProperty in tags) { var value = tagProperty.GetValue(dp); if (value != null) { writer.Write(','); writer.Write(tagProperty.LineProtocolEscapedKey); writer.Write('='); writer.Write(LineProtocolEscape.EscapeTagValue(tagProperty.GetStringValue(value))); } } } // write tag to fields seperator writer.Write(' '); // write all fields using (var enumerator = fields.GetEnumerator()) { bool hasMore = enumerator.MoveNext(); bool hasValue = false; object value = null; PropertyExpressionInfo <TInfluxRow> property = null; while (hasMore && !hasValue) { property = enumerator.Current; value = property.GetValue(dp); hasValue = value != null; hasMore = enumerator.MoveNext(); } while (hasValue) { writer.Write(property.LineProtocolEscapedKey); writer.Write('='); if (property.IsEnum) { writer.Write(LineProtocolEscape.EscapeFieldValue(property.GetStringValue(value))); } else { writer.Write(LineProtocolEscape.EscapeFieldValue(value)); } // get a hold of the next non-null value hasValue = false; while (hasMore && !hasValue) { property = enumerator.Current; value = property.GetValue(dp); hasValue = value != null; hasMore = enumerator.MoveNext(); } // we have just written a value, and now we have the next non-null value if (hasValue) { writer.Write(','); } } } // write timestamp, if exists if (timestamp != null) { var ts = timestamp.GetValue(dp); if (ts != null) { writer.Write(' '); long ticks = ((DateTime)ts).ToPrecision(precision); writer.Write(ticks); } } writer.Write('\n'); } } writer.Flush(); return(Task.FromResult(0)); }