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