Exemplo n.º 1
0
        internal DataSetValue(ValueDescriptor descriptor, object value)
        {
            Debug.Assert(descriptor != null);

            Descriptor = descriptor;
            Value      = value;
        }
 private static IEnumerable <double> ToNumbers(ValueDescriptor descriptor, CultureInfo culture, IEnumerable <object> values)
 {
     return(values
            .Select(x => ValueConversions.ToNumber(descriptor, culture, x))
            .Where(x => x.HasValue)
            .Select(x => x.Value));
 }
Exemplo n.º 3
0
        /// <summary>
        /// Infrastructure. Converts a value into the proper type required by a <see cref="ValueDescriptor"/>
        /// and then to its representation as <see cref="double"/> number.
        /// </summary>
        /// <param name="descriptor">Descriptor for which the object to convert represents the value.</param>
        /// <param name="culture">Culture used to perform conversion, if required.</param>
        /// <param name="value">
        /// Value to convert to the exact type required by <paramref name="descriptor"/> and then to
        /// its numeric representation.
        /// </param>
        /// <returns>
        /// The numeric representation of <paramref name="value"/> after it has been converted to the
        /// type required by <paramref name="descriptor"/>. If type cannot be converted to a number (for example because
        /// required type is a string) then it returns <see langword="null"/>.
        /// </returns>
        /// <exception cref="FormatException">
        /// <paramref name="value"/> cannot be converted to the type required by <paramref name="descriptor"/>
        /// using the specified culture.
        /// </exception>
        /// <exception cref="InvalidCastException">
        /// <paramref name="value"/> cannot be converted to the type required by <paramref name="descriptor"/>
        /// using the specified culture.
        /// <br/>-or-<br/>
        /// <paramref name="value"/> is a <see cref="bool"/> and required type is a <see cref="double"/>. This
        /// conversion is possible but it's probably unwanted then it's not allowed implictly.
        /// </exception>
        /// <exception cref="OverflowException">
        /// <paramref name="value"/> cannot be converted to the type required by <paramref name="descriptor"/>
        /// because it's too big or to small to be represented as a <see cref="double"/> value.
        /// </exception>
        public static double?ToNumber(ValueDescriptor descriptor, CultureInfo culture, object value)
        {
            Debug.Assert(descriptor != null);
            Debug.Assert(culture != null);

            if (descriptor.Type == TypeOfValue.String)
            {
                return(null);
            }

            if (descriptor.Type == TypeOfValue.Boolean)
            {
                return(ToBoolean(culture, value) ? 1 : 0);
            }

            if (value is bool)
            {
                throw new InvalidCastException("Required type is System.Double, cannot automatically convert from System.Boolean values.");
            }

            // Null for doubles are simply ignored, it's not safe to assume 0 here
            if (value == null)
            {
                return(null);
            }

            return((double)Convert.ChangeType(value, typeof(double), culture));
        }
 public static IEnumerable <object> Project(ValueDescriptor descriptor, CultureInfo culture, IEnumerable <object> values, NCalc.Expression expression)
 {
     return(values.Select(x =>
     {
         expression.Parameters[ExpressionEvaluator.IdentifierValue] = x;
         return expression.Evaluate();
     }));
 }
        public object Evaluate(ValueDescriptor descriptor, string expression)
        {
            Debug.Assert(descriptor != null);

            _descriptor        = new Lazy <ValueDescriptor>(() => descriptor);
            _currentExpression = CreateExpression(expression);
            return(_currentExpression.Evaluate());
        }
Exemplo n.º 6
0
        internal DataError(IssueSeverity severity, ValueDescriptor item, string message)
        {
            Debug.Assert(!String.IsNullOrWhiteSpace(message));

            Severity = severity;
            Item     = item;
            Message  = message;
        }
        public static object Average(ValueDescriptor descriptor, CultureInfo culture, IEnumerable <object> values)
        {
            var numbers = ToNumbers(descriptor, culture, values);

            if (numbers.Any())
            {
                return(numbers.Sum() / numbers.Count());
            }

            return(null);
        }
Exemplo n.º 8
0
        private IEnumerable <object> Filter(ValueDescriptor descriptor, IEnumerable <object> values)
        {
            Debug.Assert(descriptor != null);
            Debug.Assert(values != null);

            if (descriptor.PreferredAggregation == AggregationMode.Count && Options.HasFlag(AggregationOptions.ExcludeNullValuesFromCount))
            {
                return(values.Where(x => x != null));
            }

            return(values);
        }
Exemplo n.º 9
0
        public IEnumerable <object> this[ValueDescriptor descriptor]
        {
            get
            {
                Debug.Assert(descriptor != null);
                Debug.Assert(_items != null);

                List <object> values;
                if (_items.TryGetValue(descriptor, out values))
                {
                    return(values);
                }

                return(Enumerable.Empty <object>());
            }
        }
Exemplo n.º 10
0
        /// <summary>
        /// Adds a new value to this dataset associated with the specified <see cref="ValueDescriptor"/>.
        /// </summary>
        /// <param name="descriptor">Reference ID for the descriptor of this value.</param>
        /// <param name="value">
        /// Value to add to the dataset, when required it will be converted to the proper data type mandated
        /// by its descriptor (eventually using <see cref="Culture"/> for the conversion).
        /// </param>
        /// <returns>The newly added value.</returns>
        /// <exception cref="ArgumentNullException">
        /// If <paramref name="descriptor"/> is <see langword="null"/>.
        /// </exception>
        /// <exception cref="ArgumentException">
        /// If <paramref name="descriptor"/> does not belong to <see cref="Protocol"/>.
        /// </exception>
        public DataSetValue AddValue(ValueDescriptor descriptor, object value)
        {
            Debug.Assert(_cachedDescriptorsLookUp != null);

            if (descriptor == null)
            {
                throw new ArgumentNullException(nameof(descriptor));
            }

            if (!_cachedDescriptorsLookUp.ContainsKey(descriptor.Reference))
            {
                throw new ArgumentException("Specified descriptor does not belong to the protocol associated with this object.", nameof(descriptor));
            }

            return(AddValueCore(descriptor, value));
        }
Exemplo n.º 11
0
        private DataSetValue AddValueCore(ValueDescriptor descriptor, object value)
        {
            Debug.Assert(Values != null);
            Debug.Assert(descriptor != null && !String.IsNullOrWhiteSpace(descriptor.Reference));

            // TryGetValue() approach is faster but it's easier to keep DataSetValue immutable
            // because we do not need to track external changes and we just use IsChangedAfterLastCalculation.
            Values.Remove(descriptor.Reference);

            var item = new DataSetValue(descriptor, value);

            Values.Add(descriptor.Reference, item);

            IsChangedAfterLastCalculation = true;

            return(item);
        }
Exemplo n.º 12
0
        private bool IsEnabled(ValueDescriptor descriptor)
        {
            Debug.Assert(descriptor != null);

            if (String.IsNullOrWhiteSpace(descriptor.EnabledIfExpression))
            {
                return(true);
            }

            bool enabled;

            if (_evaluator.Evaluate(() => descriptor.EnabledIfExpression, out enabled))
            {
                return(enabled);
            }

            return(false);
        }
Exemplo n.º 13
0
        private object Aggregate(DataSet dataset, ValueDescriptor descriptor, IEnumerable <object> values)
        {
            Debug.Assert(descriptor != null);
            Debug.Assert(values != null);
            Debug.Assert(_accumulator.IsEmpty || _culture != null);

            if (!String.IsNullOrWhiteSpace(descriptor.AggregationExpression))
            {
                var evaluator = new ExpressionEvaluator(dataset);
                evaluator.AddConstant(ExpressionEvaluator.IdentifierValues, values);

                return(evaluator.Evaluate(() => descriptor.AggregationExpression));
            }

            // TODO: AggregationMode.None may be checked at the very beginning, no need to create a
            // list of values if there is nothing to do with them...
            if (descriptor.PreferredAggregation == AggregationMode.None)
            {
                return(null);
            }

            if (descriptor.PreferredAggregation == AggregationMode.Count)
            {
                return(values.Count());
            }

            var numbers = values
                          .Select(x => ValueConversions.ToNumber(descriptor, _culture, x))
                          .Where(x => x.HasValue);

            // Sum of an empty set is zero but average is null
            if (descriptor.PreferredAggregation == AggregationMode.Sum)
            {
                return(numbers.Sum());
            }

            if (descriptor.PreferredAggregation == AggregationMode.Average)
            {
                return(numbers.Any() ? (object)(numbers.Sum() / numbers.Count()) : null);
            }

            throw new NotSupportedException();
        }
Exemplo n.º 14
0
        private object Transform(DataSet dataset, ValueDescriptor descriptor, object value)
        {
            Debug.Assert(dataset != null);
            Debug.Assert(descriptor != null);

            if (String.IsNullOrWhiteSpace(descriptor.TransformationForAggregationExpression))
            {
                return(value);
            }

            var evaluator = new ExpressionEvaluator(dataset);

            evaluator.AddConstant(ExpressionEvaluator.IdentifierValue, value);
            evaluator.AddConstant(descriptor.Reference, value);

            // If there is an error in this expression then we accumulate a null value instead of untransformed
            // one because there are less chances it will cause more errors later. If option AggregationOptions.IgnoreAggregationErrors
            // is specified then Issues collection of the result dataset will contain this error for each accumulated value.
            return(evaluator.Evaluate(() => descriptor.TransformationForAggregationExpression));
        }
 public static object Sum(ValueDescriptor descriptor, CultureInfo culture, IEnumerable <object> values)
 {
     return(ToNumbers(descriptor, culture, values).Sum());
 }
Exemplo n.º 16
0
 internal void AddWarning(ValueDescriptor item, string message)
 {
     Add(new DataError(IssueSeverity.Warning, item, message));
 }
Exemplo n.º 17
0
 internal void AddValidationError(ValueDescriptor item, string message)
 {
     Add(new DataError(IssueSeverity.ValidationError, item, message));
 }
Exemplo n.º 18
0
 internal void AddModelError(ValueDescriptor item, string message)
 {
     Add(new DataError(IssueSeverity.ModelError, item, message));
 }
 public static object Count(ValueDescriptor descriptor, CultureInfo culture, IEnumerable <object> values)
 {
     return(values.Count());
 }