예제 #1
0
        /// <summary>
        /// Determines whether a given type supports arithmetic operations
        /// </summary>
        /// <param name="queryScalarType">The type to test for arithmetic operation support</param>
        /// <returns>A boolean value indicating whether the type supports arithmetic operations</returns>
        protected bool SupportsArithmeticOperations(QueryScalarType queryScalarType)
        {
            foreach (QueryBinaryOperation op in this.arithmeticOperations)
            {
                if (!queryScalarType.Supports(op))
                {
                    return(false);
                }
            }

            return(true);
        }
예제 #2
0
        /// <summary>
        /// Checks whether 2 QueryScalarTypes are representing the same type.
        /// </summary>
        /// <param name="type1">The first scalar type.</param>
        /// <param name="type2">The second scalar type.</param>
        /// <returns>True if the scalar types are the same, false otherwise.</returns>
        public static bool IsSameQueryScalarType(this QueryScalarType type1, QueryScalarType type2)
        {
            // All query scalar types have clr types, its sufficient to filter out constants that the same clr type.
            var clrType1 = type1 as IQueryClrType;
            var clrType2 = type2 as IQueryClrType;

            ExceptionUtilities.Assert(clrType1 != null, "Scalar Types must always have a Clr type");
            ExceptionUtilities.Assert(clrType2 != null, "Scalar Types must always have a Clr type");

            if (clrType1.ClrType == clrType2.ClrType)
            {
                return(true);
            }

            return(false);
        }
        /// <summary>
        /// Compares the given values of the given type, and throws a DataComparisonException or AssertionFailedException if values don't match
        /// </summary>
        /// <param name="type">The expected type</param>
        /// <param name="expected">The expected value</param>
        /// <param name="actual">The actual value</param>
        /// <param name="assert">The assertion handler to use</param>
        protected virtual void Compare(QueryScalarType type, object expected, object actual, AssertionHandler assert)
        {
            ExceptionUtilities.CheckArgumentNotNull(type, "type");
            ExceptionUtilities.CheckArgumentNotNull(assert, "assert");

            if (expected == type.NullValue.Value)
            {
                assert.IsNull(actual, "Primitive value unexpectedly non-null");
            }
            else
            {
                assert.IsNotNull(actual, "Primitive value unexpectedly null");

                assert.AreEqual(expected.GetType(), actual.GetType(), EqualityComparer<Type>.Default, "Types did not match");

                var comparer = new DelegateBasedEqualityComparer<QueryScalarValue>((v1, v2) => v1.Type.EvaluationStrategy.Compare(v1, v2) == 0);
                assert.AreEqual(type.CreateValue(expected), type.CreateValue(actual), comparer, "Primitive value did not match");
            }
        }
        /// <summary>
        /// Build the collection of primitive types which will be set on the constructed repository
        /// </summary>
        /// <param name="queryTypeLibrary">Query Type Library to build Types from</param>
        protected override void BuildPrimitiveTypes(QueryTypeLibrary queryTypeLibrary)
        {
            this.intType = (QueryScalarType)queryTypeLibrary.GetDefaultQueryType(EdmDataTypes.Int32);
            this.stringType = (QueryScalarType)queryTypeLibrary.GetDefaultQueryType(EdmDataTypes.String());

            this.PrimitiveTypes = new List<QueryScalarType>()
            {
                // this is just a sample
                this.intType,
                this.stringType,
                (QueryScalarType)queryTypeLibrary.GetDefaultQueryType(EdmDataTypes.Boolean),
                (QueryScalarType)queryTypeLibrary.GetDefaultQueryType(EdmDataTypes.DateTime()),
                (QueryScalarType)queryTypeLibrary.GetDefaultQueryType(EdmDataTypes.Decimal()),
                (QueryScalarType)queryTypeLibrary.GetDefaultQueryType(EdmDataTypes.Int64),
                (QueryScalarType)queryTypeLibrary.GetDefaultQueryType(EdmDataTypes.Int16),
                (QueryScalarType)queryTypeLibrary.GetDefaultQueryType(EdmDataTypes.Byte),
                (QueryScalarType)queryTypeLibrary.GetDefaultQueryType(EdmDataTypes.Single),
                (QueryScalarType)queryTypeLibrary.GetDefaultQueryType(EdmDataTypes.Double),
                (QueryScalarType)queryTypeLibrary.GetDefaultQueryType(EdmDataTypes.Binary()),
                (QueryScalarType)queryTypeLibrary.GetDefaultQueryType(EdmDataTypes.Guid),
            };
        }
예제 #5
0
 /// <summary>
 /// Sets query types for a given Enum Type
 /// </summary>
 /// <param name="enumType">The enum type</param>
 /// <param name="queryType">The corresponding query type.</param>
 internal void SetQueryEnumType(EnumType enumType, QueryScalarType queryType)
 {
     this.defaultQueryEnumTypes[enumType] = queryType;
 }
예제 #6
0
        /// <summary>
        /// Determines whether data of this type can do certain operation with data of another type
        /// </summary>
        /// <param name="operation">the operation</param>
        /// <param name="otherScalarType">the other data type</param>
        /// <returns>Value <c>true</c> if operation can be performed; otherwise, <c>false</c>.</returns>
        public bool Supports(QueryBinaryOperation operation, QueryScalarType otherScalarType)
        {
            ExceptionUtilities.CheckArgumentNotNull(otherScalarType, "otherScalarType");

            return this.EvaluationStrategy.Supports(operation, this, otherScalarType);
        }
예제 #7
0
        /// <summary>
        /// Determines whether a given type supports arithmetic operations
        /// </summary>
        /// <param name="queryScalarType">The type to test for arithmetic operation support</param>
        /// <returns>A boolean value indicating whether the type supports arithmetic operations</returns>
        protected bool SupportsArithmeticOperations(QueryScalarType queryScalarType)
        {
            foreach (QueryBinaryOperation op in this.arithmeticOperations)
            {
                if (!queryScalarType.Supports(op))
                {
                    return false;
                }
            }

            return true;
        }
        /// <summary>
        /// Evaluates canonical function.
        /// </summary>
        /// <param name="resultType">The function result type.</param>
        /// <param name="classType">Type of the class.</param>
        /// <param name="methodName">Name of the method.</param>
        /// <param name="arguments">The arguments for the function call.</param>
        /// <returns>
        /// Query value which is the result of the function evaluation.
        /// </returns>
        private QueryValue EvaluateMethod(QueryScalarType resultType, Type classType, string methodName, params QueryScalarValue[] arguments)
        {
            var argsTypes = arguments.Select(a => ((IQueryClrType)a.Type).ClrType).ToArray();
            var method = classType.GetMethod(methodName, argsTypes);
            if (method == null)
            {
                argsTypes = argsTypes.Skip(1).ToArray();
                method = classType.GetMethod(methodName, argsTypes, true, false);
            }

            ExceptionUtilities.CheckObjectNotNull(method, "Could not find instance or static method '{0}' on type '{1}'", methodName, classType.FullName);

            object[] argsValues = arguments.Select(a => a.Value).ToArray();

            object value = null;
            if (method.IsStatic)
            {
                value = method.Invoke(null, argsValues);
            }
            else if (argsValues[0] != null)
            {
                // null needs to be propagated for instance methods, otherwise this will fail
                value = method.Invoke(argsValues[0], argsValues.Skip(1).ToArray());
            }

            return resultType.CreateValue(value);
        }
        /// <summary>
        /// Determines whether a typed data can do certain operation with another typed data
        /// </summary>
        /// <param name="operation">the operation</param>
        /// <param name="sourceType">the type of data to operation on</param>
        /// <param name="otherType">the other type</param>
        /// <returns>Value <c>true</c> if operation can be performed; otherwise, <c>false</c>.</returns>
        public override bool Supports(QueryBinaryOperation operation, QueryScalarType sourceType, QueryScalarType otherType)
        {
            if (this.IsSpatialType((IQueryClrType)sourceType) || this.IsSpatialType((IQueryClrType)otherType))
            {
                return false;
            }

            return base.Supports(operation, sourceType, otherType);
        }
 /// <summary>
 /// Gets the common type to which both types can be promoted.
 /// </summary>
 /// <param name="leftType">First type.</param>
 /// <param name="rightType">Second type.</param>
 /// <returns>Common type to which both types can be promoted. Throws if unable to find a common type.</returns>
 public QueryScalarType GetCommonType(QueryScalarType leftType, QueryScalarType rightType)
 {
     throw new TaupoNotSupportedException("Attempt to use evaluation strategy from " + typeof(QueryUnresolvedType).Name + ". Please resolve expression first.");
 }
 /// <summary>
 /// Casts a <see cref="QueryScalarValue"/> to a <see cref="QueryScalarType"/>. The cast will return the value type cast to the new type.
 /// </summary>
 /// <param name="source">The source for the cast operation.</param>
 /// <param name="type">The type for the cast operation.</param>
 /// <returns><see cref="QueryScalarValue"/> which is cast to the appropriate type</returns>
 public QueryScalarValue Cast(QueryScalarValue source, QueryScalarType type)
 {
     throw new TaupoNotSupportedException("Attempt to use evaluation strategy from " + typeof(QueryUnresolvedType).Name + ". Please resolve expression first.");
 }
예제 #12
0
        /// <summary>
        /// Transforms a value from one scalar type to another.
        /// </summary>
        /// <param name="valueToTransform">The value to transform.</param>
        /// <param name="targetType">The target type of the value.</param>
        /// <returns>The value transformed to the target type.</returns>
        public static QueryScalarValue MaterializeValueIfEnum(this QueryScalarValue valueToTransform, QueryScalarType targetType)
        {
            ExceptionUtilities.CheckArgumentNotNull(targetType, "targetType");
            var clrType = ((IQueryClrType)targetType).ClrType;

            Type   clrEnumType;
            object enumValue = null;

            if (TryExtractEnumType(clrType, out clrEnumType))
            {
                if (valueToTransform.Value != null)
                {
                    enumValue = Enum.ToObject(clrEnumType, valueToTransform.Value);
                }

                return(targetType.CreateValue(enumValue));
            }
            else
            {
                return(valueToTransform);
            }
        }
        private void UpdateRootScalarBag(QueryCollectionValue instance, IEnumerable<NamedValue> namedValues, QueryScalarType scalarElementDataType)
        {
            int i = 0;

            var scalarCollection = new List<QueryValue>();
            List<NamedValue> scalarItemNamedValues = namedValues.Where(pp => pp.Name == i.ToString(CultureInfo.InvariantCulture)).ToList();
            while (scalarItemNamedValues.Any())
            {
                ExceptionUtilities.Assert(scalarItemNamedValues.Count() < 2, "Should not get more than one value for a scalar Bag item for path '{0}'", i.ToString(CultureInfo.InvariantCulture));
                var value = scalarItemNamedValues.Single();
                scalarCollection.Add(scalarElementDataType.CreateValue(value.Value));
                this.unusedNamedValuePaths.Remove(value.Name);

                i++;
                scalarItemNamedValues = namedValues.Where(pp => pp.Name == i.ToString(CultureInfo.InvariantCulture)).ToList();
            }

            if (scalarCollection.Any())
            {
                this.SetCollectionValue(instance, scalarCollection);
            }
        }
        private void UpdateScalarBag(QueryStructuralValue instance, QueryProperty memberProperty, string propertyPath, IEnumerable<NamedValue> namedValues, QueryScalarType scalarElementDataType)
        {
            int i = 0;

            var scalarCollection = new List<QueryValue>();
            List<NamedValue> scalarItemNamedValues = namedValues.Where(pp => pp.Name == propertyPath + "." + i).ToList();
            while (scalarItemNamedValues.Any())
            {
                ExceptionUtilities.Assert(scalarItemNamedValues.Count() < 2, "Should not get more than one value for a scalar Bag item for path '{0}'", propertyPath + "." + i);
                var value = scalarItemNamedValues.Single();
                scalarCollection.Add(scalarElementDataType.CreateValue(value.Value));
                this.unusedNamedValuePaths.Remove(value.Name);

                i++;
                scalarItemNamedValues = namedValues.Where(pp => pp.Name == propertyPath + "." + i).ToList();
            }

            if (scalarCollection.Any())
            {
                this.SetCollectionProperty(instance, memberProperty, scalarCollection);
            }
        }
        /// <summary>
        /// Evaluates the property.
        /// </summary>
        /// <param name="resultType">Type of the result.</param>
        /// <param name="propertyName">Name of the property.</param>
        /// <param name="instance">The instance.</param>
        /// <returns>
        /// Query value which is the result of the function evaluation.
        /// </returns>
        private QueryValue EvaluateProperty(QueryScalarType resultType, string propertyName, QueryScalarValue instance)
        {
            if (instance.Value == null)
            {
                // TODO: evaluation error?
                return resultType.NullValue;
            }

            var type = instance.Value.GetType();
            var propertyInfo = type.GetProperty(propertyName);
            ExceptionUtilities.CheckObjectNotNull(propertyInfo, "Could not find property named '{0}' on '{1}'", propertyName, instance.Value);

            var value = propertyInfo.GetValue(instance.Value, null);
            return resultType.CreateValue(value);
        }
        /// <summary>
        /// Compares the given values of the given type, and throws a DataComparisonException or AssertionFailedException if values don't match
        /// </summary>
        /// <param name="type">The expected type</param>
        /// <param name="expected">The expected value</param>
        /// <param name="actual">The actual value</param>
        /// <param name="assert">The assertion handler to use</param>
        protected override void Compare(QueryScalarType type, object expected, object actual, AssertionHandler assert)
        {
            expected = this.Converter.Normalize(expected);
            actual = this.Converter.Normalize(actual);

            base.Compare(type, expected, actual, assert);
        }
예제 #17
0
 private bool ScalarTypesAreEqualComparable(QueryScalarType firstScalarType, QueryScalarType secondScalarType)
 {
     return(firstScalarType.Supports(QueryBinaryOperation.EqualTo, secondScalarType));
 }
 /// <summary>
 /// Removes any length constraints from the type
 /// </summary>
 /// <param name="type">The type from which to remove the constraints</param>
 /// <returns>The new type with length constraints removed.</returns>
 public QueryScalarType RemoveLengthConstraints(QueryScalarType type)
 {
     throw new TaupoNotSupportedException("Attempt to use evaluation strategy from " + typeof(QueryUnresolvedType).Name + ". Please resolve expression first.");
 }
예제 #19
0
        /// <summary>
        /// Factory method to create the <see cref="QueryConstantExpression"/>.
        /// </summary>
        /// <param name="value">Value of the expression.</param>
        /// <param name="valueType">Type of the expression.</param>
        /// <returns>The <see cref="QueryConstantExpression"/> with the provided arguments.</returns>
        public static QueryConstantExpression Constant(object value, QueryScalarType valueType)
        {
            ExceptionUtilities.CheckArgumentNotNull(valueType, "valueType");

            if (value == null)
            {
                ExceptionUtilities.Assert(!valueType.IsUnresolved, "When value is null type cannot be unresolved.");
            }

            return Constant(valueType.CreateValue(value));
        }
 /// <summary>
 /// Determines whether an operation between two types is supported
 /// </summary>
 /// <param name="operation">the operation</param>
 /// <param name="sourceType">the type of data to operation on</param>
 /// <param name="otherType">the other type</param>
 /// <returns>Value <c>true</c> if operation can be performed; otherwise, <c>false</c>.</returns>
 public bool Supports(QueryBinaryOperation operation, QueryScalarType sourceType, QueryScalarType otherType)
 {
     throw new TaupoNotSupportedException("Attempt to use evaluation strategy from " + typeof(QueryUnresolvedType).Name + ". Please resolve expression first.");
 }
예제 #21
0
        /// <summary>
        /// Determines whether data of this type can do certain operation with data of another type
        /// </summary>
        /// <param name="operation">the operation</param>
        /// <param name="otherScalarType">the other data type</param>
        /// <returns>Value <c>true</c> if operation can be performed; otherwise, <c>false</c>.</returns>
        public bool Supports(QueryBinaryOperation operation, QueryScalarType otherScalarType)
        {
            ExceptionUtilities.CheckArgumentNotNull(otherScalarType, "otherScalarType");

            return(this.EvaluationStrategy.Supports(operation, this, otherScalarType));
        }
 /// <summary>
 /// Determines whether a type supports ordering.
 /// </summary>
 /// <param name="sourceType">the type of data to operation on</param>
 /// <returns>Value <c>true</c> if ordering can be performed; otherwise, <c>false</c>.</returns>
 public bool SupportsOrderComparison(QueryScalarType sourceType)
 {
     throw new TaupoNotSupportedException("Attempt to use evaluation strategy from " + typeof(QueryUnresolvedType).Name + ". Please resolve expression first.");
 }