예제 #1
0
        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));
        }
예제 #2
0
        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);
            }
        }
예제 #3
0
        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));
        }