Esempio n. 1
0
 private static bool HasAllColumns(DatabaseMeasurementInfo meta, List <string> columns)
 {
     foreach (var fieldOrTag in columns)
     {
         if (fieldOrTag != InfluxConstants.KeyColumn && fieldOrTag != InfluxConstants.TimeColumn && !meta.Tags.Contains(fieldOrTag) && !meta.Fields.Contains(fieldOrTag))
         {
             return(false);
         }
     }
     return(true);
 }
Esempio n. 2
0
        internal async Task <DatabaseMeasurementInfo> GetMetaInformationAsync(string db, string measurementName, TimeSpan?expiration)
        {
            var key = new DatabaseMeasurementInfoKey(db, measurementName);
            DatabaseMeasurementInfo info;

            lock (_seriesMetaCache)
            {
                _seriesMetaCache.TryGetValue(key, out info);
            }

            var now = DateTime.UtcNow;

            if (info != null)
            {
                if (!expiration.HasValue) // info never expires
                {
                    return(info);
                }

                if (now - info.Timestamp < expiration.Value) // has not expired
                {
                    return(info);
                }
            }

            // has expired or never existed, lets retrieve it

            // get metadata information from the store
            var tagsResult = await this.ShowTagKeysAsync(db, measurementName).ConfigureAwait(false);

            var tags = tagsResult.Series.FirstOrDefault()?.Rows;

            info = new DatabaseMeasurementInfo(now);
            if (tags != null)
            {
                foreach (var row in tags)
                {
                    info.Tags.Add(row.TagKey);
                }
            }

            lock (_seriesMetaCache)
            {
                _seriesMetaCache[key] = info;
            }

            return(info);
        }
Esempio n. 3
0
        internal async Task <DatabaseMeasurementInfo> GetMetaInformationAsync(string db, string measurementName, bool forceRefresh)
        {
            var key = new DatabaseMeasurementInfoKey(db, measurementName);
            DatabaseMeasurementInfo info;

            if (!forceRefresh)
            {
                lock ( _seriesMetaCache )
                {
                    if (_seriesMetaCache.TryGetValue(key, out info))
                    {
                        return(info);
                    }
                }
            }

            // get metadata information from the store
            var fieldTask = ShowFieldKeysAsync(db, measurementName);
            var tagTask   = ShowTagKeysAsync(db, measurementName);
            await Task.WhenAll(fieldTask, tagTask).ConfigureAwait(false);

            var fields = fieldTask.Result.Series.FirstOrDefault()?.Rows;
            var tags   = tagTask.Result.Series.FirstOrDefault()?.Rows;

            info = new DatabaseMeasurementInfo();
            if (fields != null)
            {
                foreach (var row in fields)
                {
                    info.Fields.Add(row.FieldKey);
                }
            }
            if (tags != null)
            {
                foreach (var row in tags)
                {
                    info.Tags.Add(row.TagKey);
                }
            }

            lock ( _seriesMetaCache )
            {
                _seriesMetaCache[key] = info;
            }

            return(info);
        }
Esempio n. 4
0
        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);
            }
        }
Esempio n. 5
0
        private async static Task <InfluxResultSet <TInfluxRow> > CreateBasedOnInterfaceAsync <TInfluxRow>(
            InfluxClient client,
            QueryResult queryResult,
            string db,
            bool isExclusivelyFields)
            where TInfluxRow : new()
        {
            // In this case, we will contruct objects based on the IInfluxRow interface
            List <InfluxResult <TInfluxRow> > results = new List <InfluxResult <TInfluxRow> >();

            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>();
                        var setters    = new Action <IInfluxRow, string, object> [columns.Count];

                        // Values will be null, if there are no entries in the result set
                        if (series.Values != null)
                        {
                            // Get metadata information about the measurement we are querying, as we dont know
                            // which columns are tags/fields otherwise
                            DatabaseMeasurementInfo meta = null;
                            if (!isExclusivelyFields)
                            {
                                // get the required metadata
                                meta = await client.GetMetaInformationAsync(db, name, false).ConfigureAwait(false);

                                // check that we have all columns, otherwise call method again
                                bool hasAllColumnsAndTags = HasAllColumns(meta, columns);
                                if (!hasAllColumnsAndTags)
                                {
                                    // if we dont have all columns, attempt to query the metadata again (might have changed since last query)
                                    meta = await client.GetMetaInformationAsync(db, name, false).ConfigureAwait(false);

                                    hasAllColumnsAndTags = HasAllColumns(meta, columns);

                                    // if we still dont have all columns, we cant do anything, throw exception
                                    if (!hasAllColumnsAndTags)
                                    {
                                        throw new InfluxException(Errors.IndeterminateColumns);
                                    }
                                }
                            }

                            for (int i = 0; i < columns.Count; i++)
                            {
                                var columnName = columns[i];

                                if (isExclusivelyFields)
                                {
                                    setters[i] = (row, fieldName, value) => row.SetField(fieldName, value);
                                }
                                else if (columnName == InfluxConstants.TimeColumn)
                                {
                                    setters[i] = (row, timeName, value) => row.SetTimestamp(long.Parse(value.ToString()));
                                }
                                else if (meta.Tags.Contains(columnName))
                                {
                                    setters[i] = (row, tagName, value) => row.SetTag(tagName, (string)value);
                                }
                                else if (meta.Fields.Contains(columnName))
                                {
                                    setters[i] = (row, fieldName, value) => row.SetField(fieldName, value);
                                }
                                else
                                {
                                    throw new InfluxException(string.Format(Errors.InvalidColumn, columnName));
                                }
                            }

                            // constructs the IInfluxRows using the IInfluxRow interface
                            foreach (var values in series.Values)
                            {
                                var dataPoint = (IInfluxRow) 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;
                                }

                                // 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((TInfluxRow)dataPoint);
                            }
                        }

                        // create new dictionary, with correct typing
                        var tags = series.Tags?.ToDictionary(x => x.Key, x => x.Value == string.Empty ? null : (object)x.Value) ?? null;

                        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));
        }