Beispiel #1
0
        internal InfluxRowTypeInfo(
            PropertyExpressionInfo <TInfluxRow> timestamp,
            List <PropertyExpressionInfo <TInfluxRow> > tags,
            List <PropertyExpressionInfo <TInfluxRow> > fields,
            List <PropertyExpressionInfo <TInfluxRow> > all)
        {
            Timestamp           = timestamp;
            Tags                = new List <PropertyExpressionInfo <TInfluxRow> >(tags.OrderBy(x => x.Key, StringComparer.Ordinal));
            Fields              = new List <PropertyExpressionInfo <TInfluxRow> >(fields.OrderBy(x => x.Key, StringComparer.Ordinal));
            All                 = new ReadOnlyDictionary <string, PropertyExpressionInfo <TInfluxRow> >(all.ToDictionary(x => x.Key, x => x));
            PropertiesByClrName = All.ToDictionary(x => x.Value.Property.Name, x => x.Value);

            var newLambda = Expression.Lambda <Func <TInfluxRow> >(Expression.New(typeof(TInfluxRow)), true);

            New = newLambda.Compile();
        }
        internal static InfluxRowTypeInfo <TInfluxRow> GetOrCreate <TInfluxRow>()
            where TInfluxRow : new()
        {
            lock ( _sync )
            {
                object cache;
                var    type = typeof(TInfluxRow);

                if (!_typeCache.TryGetValue(type, out cache))
                {
                    var tags   = new List <PropertyExpressionInfo <TInfluxRow> >();
                    var fields = new List <PropertyExpressionInfo <TInfluxRow> >();
                    var all    = new List <PropertyExpressionInfo <TInfluxRow> >();
                    PropertyExpressionInfo <TInfluxRow> timestamp = null;
                    foreach (var propertyInfo in type.GetProperties(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public))
                    {
                        var fieldAttribute     = propertyInfo.GetCustomAttribute <InfluxFieldAttribute>();
                        var tagAttribute       = propertyInfo.GetCustomAttribute <InfluxTagAttribute>();
                        var timestampAttribute = propertyInfo.GetCustomAttribute <InfluxTimestampAttribute>();

                        // list all attributes so we can ensure the attributes specified on a property are valid
                        var allAttributes = new Attribute[] { fieldAttribute, tagAttribute, timestampAttribute }
                        .Where(x => x != null)
                        .ToList();

                        if (allAttributes.Count > 1)
                        {
                            throw new InfluxException(string.Format(Errors.MultipleAttributesOnSingleProperty, propertyInfo.Name, type.Name));
                        }

                        if (timestampAttribute != null)
                        {
                            timestamp = new PropertyExpressionInfo <TInfluxRow>("time", propertyInfo);

                            all.Add(timestamp);
                        }
                        else if (fieldAttribute != null)
                        {
                            var expression = new PropertyExpressionInfo <TInfluxRow>(fieldAttribute.Name, propertyInfo);
                            if (!_validFieldTypes.Contains(expression.Type) && !expression.Type.GetTypeInfo().IsEnum)
                            {
                                throw new InfluxException(string.Format(Errors.InvalidFieldType, propertyInfo.Name, type.Name));
                            }

                            if (string.IsNullOrEmpty(fieldAttribute.Name))
                            {
                                throw new InfluxException(string.Format(Errors.InvalidNameProperty, propertyInfo.Name, type.Name));
                            }

                            fields.Add(expression);
                            all.Add(expression);
                        }
                        else if (tagAttribute != null)
                        {
                            var expression = new PropertyExpressionInfo <TInfluxRow>(tagAttribute.Name, propertyInfo);
                            if (expression.Type != typeof(string) && !expression.Type.GetTypeInfo().IsEnum)
                            {
                                throw new InfluxException(string.Format(Errors.InvalidTagType, propertyInfo.Name, type.Name));
                            }

                            if (string.IsNullOrEmpty(tagAttribute.Name))
                            {
                                throw new InfluxException(string.Format(Errors.InvalidNameProperty, propertyInfo.Name, type.Name));
                            }

                            tags.Add(expression);
                            all.Add(expression);
                        }
                    }

                    cache = new InfluxRowTypeInfo <TInfluxRow>(timestamp, tags, fields, all);

                    _typeCache.Add(typeof(TInfluxRow), cache);
                }
                return((InfluxRowTypeInfo <TInfluxRow>)cache);
            }
        }
        internal static InfluxRowTypeInfo <TInfluxRow> GetOrCreate <TInfluxRow>()
            where TInfluxRow : new()
        {
            lock ( Sync )
            {
                InfluxRowTypeInfo cache;
                var type = typeof(TInfluxRow);

                if (!TypeCache.TryGetValue(type, out cache))
                {
                    Type timestampType = null;

                    var computed = new List <PropertyExpressionInfo <TInfluxRow> >();
                    var tags     = new List <PropertyExpressionInfo <TInfluxRow> >();
                    var fields   = new List <PropertyExpressionInfo <TInfluxRow> >();
                    var all      = new List <PropertyExpressionInfo <TInfluxRow> >();
                    PropertyExpressionInfo <TInfluxRow> timestamp         = null;
                    PropertyExpressionInfo <TInfluxRow> influxMeasurement = null;

                    foreach (var propertyInfo in type.GetProperties(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public))
                    {
                        var fieldAttribute             = propertyInfo.GetCustomAttribute <InfluxFieldAttribute>();
                        var tagAttribute               = propertyInfo.GetCustomAttribute <InfluxTagAttribute>();
                        var computedAttribute          = propertyInfo.GetCustomAttribute <InfluxComputedAttribute>();
                        var timestampAttribute         = propertyInfo.GetCustomAttribute <InfluxTimestampAttribute>();
                        var influxMeasurementAttribute = propertyInfo.GetCustomAttribute <InfluxMeasurementAttribute>();

                        // list all attributes so we can ensure the attributes specified on a property are valid
                        var allAttributes = new Attribute[] { fieldAttribute, tagAttribute, timestampAttribute, computedAttribute }
                        .Where(x => x != null)
                        .ToList();

                        if (allAttributes.Count > 1)
                        {
                            throw new InfluxException(string.Format(Errors.MultipleAttributesOnSingleProperty, propertyInfo.Name, type.Name));
                        }

                        if (timestampAttribute != null)
                        {
                            timestamp = new PropertyExpressionInfo <TInfluxRow>(InfluxConstants.TimeColumn, propertyInfo);

                            all.Add(timestamp);
                            timestampType = timestamp.RawType;
                        }
                        else if (fieldAttribute != null)
                        {
                            var expression = new PropertyExpressionInfo <TInfluxRow>(fieldAttribute.Name, propertyInfo);
                            if (!ValidFieldTypes.Contains(expression.Type) && !expression.Type.GetTypeInfo().IsEnum)
                            {
                                throw new InfluxException(string.Format(Errors.InvalidFieldType, propertyInfo.Name, type.Name));
                            }

                            if (string.IsNullOrEmpty(fieldAttribute.Name))
                            {
                                throw new InfluxException(string.Format(Errors.InvalidNameProperty, propertyInfo.Name, type.Name));
                            }

                            fields.Add(expression);
                            all.Add(expression);
                        }
                        else if (tagAttribute != null)
                        {
                            var expression = new PropertyExpressionInfo <TInfluxRow>(tagAttribute.Name, propertyInfo);
                            if (!ValidFieldTypes.Contains(expression.Type) && !expression.Type.GetTypeInfo().IsEnum)
                            {
                                throw new InfluxException(string.Format(Errors.InvalidTagType, propertyInfo.Name, type.Name));
                            }

                            if (string.IsNullOrEmpty(tagAttribute.Name))
                            {
                                throw new InfluxException(string.Format(Errors.InvalidNameProperty, propertyInfo.Name, type.Name));
                            }

                            tags.Add(expression);
                            all.Add(expression);
                        }
                        else if (computedAttribute != null)
                        {
                            var expression = new PropertyExpressionInfo <TInfluxRow>(computedAttribute.Name, propertyInfo);
                            if (!ValidFieldTypes.Contains(expression.Type) && !expression.Type.GetTypeInfo().IsEnum)
                            {
                                throw new InfluxException(string.Format(Errors.InvalidComputedType, propertyInfo.Name, type.Name));
                            }

                            if (string.IsNullOrEmpty(computedAttribute.Name))
                            {
                                throw new InfluxException(string.Format(Errors.InvalidNameProperty, propertyInfo.Name, type.Name));
                            }

                            computed.Add(expression);
                            all.Add(expression);
                        }
                        else if (influxMeasurementAttribute != null)
                        {
                            var expression = new PropertyExpressionInfo <TInfluxRow>(null, propertyInfo);
                            if (expression.Type != typeof(string))
                            {
                                throw new InfluxException(string.Format(Errors.InvalidMeasurementNameType, propertyInfo.Name, type.Name));
                            }

                            influxMeasurement = expression;
                        }
                    }

                    bool isBasedOnInterface = false;
                    var  genericTypeDefinitionOfImplementedInterface = GetGenericTypeDefinitionForImplementedInfluxInterface(type);
                    if (genericTypeDefinitionOfImplementedInterface != null)
                    {
                        timestampType      = genericTypeDefinitionOfImplementedInterface.GetGenericArguments()[0];
                        isBasedOnInterface = true;
                    }
                    else if (timestampType == null)
                    {
                        timestampType = typeof(NullTimestamp);
                    }

                    cache = (InfluxRowTypeInfo <TInfluxRow>) typeof(InfluxRowTypeInfo <,>)
                            .MakeGenericType(new[] { typeof(TInfluxRow), timestampType })
                            .GetConstructors(BindingFlags.Instance | BindingFlags.NonPublic)[0]
                            .Invoke(new object[] { isBasedOnInterface, timestamp, tags, fields, computed, all, influxMeasurement });
                    TypeCache.Add(typeof(TInfluxRow), cache);
                }
                return((InfluxRowTypeInfo <TInfluxRow>)cache);
            }
        }